In my ServiceStack 8 application using ASP.Net Identity configured for OpenIdConnect like so in program.cs
:
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; // Add this line
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.MetadataAddress = "https://cognito-idp.{yourAwsRegion}.amazonaws.com/{yourUserPoolId}/.well-known/openid-configuration";
options.Authority = $"https://{yourCognitoDomain}.auth.{yourAwsRegion}.amazoncognito.com";
options.ClientId = clientId;
options.ResponseType = OpenIdConnectResponseType.Code;
options.CallbackPath = "/signin-oidc";
options.SaveTokens = true;
options.Scope.Add("email");
options.Scope.Add("openid");
options.Scope.Add("phone");
options.Scope.Add("profile");
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = $"https://cognito-idp.{yourAwsRegion}.amazonaws.com/{yourUserPoolId}",
ValidateAudience = true,
ValidAudience = clientId,
ValidateLifetime = true,
NameClaimType = "name",
RoleClaimType = "cognito:groups"
};
});
services.AddAuthorization();
...
app.UseAuthentication();
app.UseAuthorization();
app.UseServiceStack(new AppHost(), options =>
{
options.MapEndpoints(useSystemJson: UseSystemJson.Never);
});
app.MapGet("/yo", [Authorize] (HttpContext context) =>
{
//this is just for testing auth.
return $"Hello {context.User.Claims.Single(r=> r.Type == "name").Value}. We see your email is: {context.User.Claims.Single(r => r.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress").Value} !";
});
I also have this TypeFilter
in the GenerateCrudServices
to ensure that all CRUD DTO’s require authentication:
TypeFilter = (type, req) =>
{
if (type.IsCrud())
{
type.AddAttribute(new Microsoft.AspNetCore.Authorization.AuthorizeAttribute());
}
The authentication flow works as expected. When I request any of the CRUD endpoints via the browser, the redirect to the auth provider happens, the user logs in, and the redirect back to the app works, and the api resource is displayed in the browser. Even the indicated “test” endpoint called ‘yo’ works and displays the username and email of the user as returned from the auth provider.
It’s the logout
that I have a problem with. When I call /auth/logout
, I get the following error:
System.Exception: Error trying to resolve Service ‘SignInManager
1' or one of its autowired dependencies. at ServiceStack.ContainerExtensions.Resolve[T](IResolver container) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Common/SimpleContainer.cs:line 123 at ServiceStack.Auth.IdentityAuthProvider
2.LogoutAsync(IServiceBase
service, Authenticate request, CancellationToken token) in
/home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.Extensions/Auth/IdentityAuthProvider.cs:line
34 at
ServiceStack.Auth.AuthenticateService.HandleLogoutAsync(Authenticate
request, IAuthProvider authProvider) in
/home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Auth/AuthenticateService.cs:line
439 at ServiceStack.Auth.AuthenticateService.PostAsync(Authenticate
request) in
/home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Auth/AuthenticateService.cs:line
276 at ServiceStack.Host.ServiceRunner`1.ExecuteAsync(IRequest req,
Object instance, TRequest requestDto) in
/home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Host/ServiceRunner.cs:line
149
There is no SignInManager registered in my config. Do I need to register one?
What am I missing?
If using ASP.NET Identity Auth with ServiceStack, you always need to register the AuthFeature
plugin, e.g:
public class ConfigureAuth : IHostingStartup
{
public void Configure(IWebHostBuilder builder) => builder
.ConfigureAppHost(appHost => {
appHost.Plugins.Add(new AuthFeature(IdentityAuth.For<ApplicationUser>(
// Configure ServiceStack's Integration with Identity Auth
options => {
options.SessionFactory = () => new CustomUserSession();
options.CredentialsAuth();
})
));
});
}
For a working example of an ASP.NET Identity Auth integration, check out ServiceStack’s Identity Auth Templates, whose source code is maintained at:
https://github.com/NetCoreTemplates/
2