Using Claims with OpenIdConnect.Server in ASP.NET 5

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; // Note: in a real world app, you'd probably prefer storing the X.509 certificate // in the user or machine store. To keep this sample easy to use, the certificate // is extracted from the Certificate.pfx file embedded in this assembly. options.UseCertificate( assembly: typeof(Startup).GetTypeInfo().Assembly, resource: "AuthExample.Certificate.pfx", password: "Owin.Security.OpenIdConnect.Server"); }); app.UseIdentity(); app.UseMvc(); } } 

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)?
+4
c # asp.net-core claims-based-identity openid-connect
Aug 30 '15 at 17:10
source share
1 answer

app.UseOpenIdConnectAuthentication() (which relies on OpenIdConnectAuthenticationMiddleware ) is intended only to support interactive streams (code / implicit / hybrid) and cannot be used with the resource owner password credential type. Since you only want to check access tokens, use app.UseOAuthBearerAuthentication() instead.

See this SO answer for more information on other OpenID Connect / OAuth2 middleware in ASP.NET 5: Configure the authorization server endpoint

How to get a resource owner’s stream to work with claims

The whole OpenIdConnectServerMiddleware you use is claims based.

If you have problems serializing specific requirements, remember that all claims, except for ClaimTypes.NameIdentifier , are not placed in identification and access tokens by default, since they are both read by the client application and user agent. To avoid confidential data leakage, you need to specify an explicit destination , indicating where you want the claims to be serialized:

 // This claim will be only serialized in the access token. identity.AddClaim(ClaimTypes.Name, username, OpenIdConnectConstants.Destinations.AccessToken); // This claim will be serialized in both the identity and the access tokens. identity.AddClaim(ClaimTypes.Surname, "Doe", OpenIdConnectConstants.Destinations.AccessToken, OpenIdConnectConstants.Destinations.IdentityToken);); 



ValidateLifetime = true or ValidateAudience = true throws an exception and results in an Http Code 500 response without a printed error.

How to turn authentication errors into 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)?

The way the OIDC client middleware (managed by MSFT) works by default, but will eventually be fixed. You can see this GitHub ticket in a workaround: https://github.com/aspnet/Security/issues/411

+2
Aug 30 '15 at 18:28
source share



All Articles