Over the past 7 days, I tried to configure ASP.NET 5 WebApi using OpenIdConnect.Server with the resource owner thread.
I was more or less successful in creating a token and accessing [Authorize] protected actions.
However, when I try to access this.User.Identity.Claims , it is empty. I am using ASP.NET 5 beta6 at the moment (problem with updating to the latest beta 7 and awaiting official release)
In Startup.cs, I got the following:
public void ConfigureServices(IServiceCollection services) { services.AddCaching(); services.AddEntityFramework() .AddSqlServer() .AddDbContext<AuthContext>(options => { options.UseSqlServer(Configuration.Get("Data:DefaultConnection:ConnectionString")); }); services.AddIdentity<AuthUser, AuthRole>( options => options.User = new Microsoft.AspNet.Identity.UserOptions { RequireUniqueEmail = true, UserNameValidationRegex = "^[a-zA-Z0-9@_\\.-]+$" }) .AddEntityFrameworkStores<AuthContext, Guid>() .AddDefaultTokenProviders(); services.ConfigureCors(configure => { configure.AddPolicy("CorsPolicy", builder => { builder.WithOrigins("http:/localhost/", "http://win2012.bludev.com/"); }); }); services.AddScoped<IAuthRepository, AuthRepository>(); } public void Configure(IApplicationBuilder app) { var factory = app.ApplicationServices.GetRequiredService<ILoggerFactory>(); factory.AddConsole(); app.UseStaticFiles(); app.UseOAuthBearerAuthentication(options => { options.Authority = "http://win2012.bludev.com/api/auth/"; options.Audience = "http://win2012.bludev.com/"; options.AutomaticAuthentication = true; options.TokenValidationParameters = new TokenValidationParameters() { RequireExpirationTime = true, RequireSignedTokens = true, RoleClaimType = ClaimTypes.Role, NameClaimType = ClaimTypes.NameIdentifier, ValidateActor = true, ValidateAudience = false, ValidateIssuer = true, ValidateLifetime = false, ValidateIssuerSigningKey = true, ValidateSignature = true, ValidAudience = "http://win2012.bludev.com/", ValidIssuer = "http://win2012.bludev.com/" }; }); app.UseOpenIdConnectServer(options => { options.Issuer = new Uri("http://win2012.bludev.com/api/auth/"); options.AllowInsecureHttp = true; options.AuthorizationEndpointPath = PathString.Empty; options.Provider = new AuthorizationProvider(); options.ApplicationCanDisplayErrors = true;
I used app.UseOAuthBearerAuthentication because I could not get app.UseOpenIdConnectAuthentication , all I would get is in the console:
request: / admin / user / warning: [Microsoft.AspNet.Authentication.OpenIdConnect.OpenIdConnectAuthentica tionMiddleware] OIDCH_0004: OpenIdConnectAuthenticationHandler: message.State is null or empty. request: /.well-known/openid-configuration warning: [Microsoft.AspNet.Authentication.OpenIdConnect.OpenIdConnectAuthentica tionMiddleware] OIDCH_0004: OpenIdConnectAuthenticationHandler: message.State is null or empty.
and exception after time
error: [Microsoft.AspNet.Server.WebListener.MessagePump] ProcessRequestAsync System.InvalidOperationException: IDX10803: cannot create to get configuration from: ' http://win2012.bludev.com/api/auth/.well-known/openid-configuration ', in Microsoft.IdentityModel.Logging.LogHelper.Throw (String message, Type excePype, EventLevel logLevel, innerException) with Microsoft.IdentityModel.Protocols.ConfigurationManager`1.d__24.MoveNext () --- End stack trace from previous location where the exception was thrown is on System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Task tasks) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot (Task task) ...
With this configuration UseOpenIdConnectAuthentication
app.UseOpenIdConnectAuthentication(options => { options.AuthenticationScheme = OpenIdConnectAuthenticationDefaults.AuthenticationScheme; options.Authority = "http://win2012.bludev.com/api/auth/"; options.Audience = "http://win2012.bludev.com/"; options.Resource = "http://win2012.bludev.com/"; options.AutomaticAuthentication = true; options.TokenValidationParameters = new TokenValidationParameters() { RequireExpirationTime = true, RequireSignedTokens = true, RoleClaimType = ClaimTypes.Role, NameClaimType = ClaimTypes.NameIdentifier, ValidateActor = true, ValidateAudience = false, ValidateIssuer = true, ValidateLifetime = false, ValidateIssuerSigningKey = true, ValidateSignature = true }; });
So the real question is:
- How to get a resource owner flow to work with claims.
ValidateLifetime = true or ValidateAudience = true will throw an exception and raise an Http Code 500 response without a printed error.- How to include authentication in meaningful 400/403 code and json or xml respones (depending on client preferences) that will be displayed to the user? (JavaScript in this case is the client)?