SignalR authentication with Blazor wasm Bearer Token - asp.net-core

I authenticated to Signalr with Bearer token and signalr said Authentication was
successful.
But Signalr Hub Context.Identity.User.Name is null after authentication.
How can i access to authenticated user information in SignalR Hub for connectionid and user mapping.
My Startup.cs code for authentication.
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.Authority = "https://security.minima.local";
options.Audience = "blazor_web_app_api";
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new
TokenValidationParameters()
{
ValidateAudience = false
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments("/notification")))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
})
.AddIdentityServerJwt();

You need to tell the TokenValidator which claim is the name and role claim and you do that by setting:
.AddMyJwtBearer(opt =>
{
...
opt.TokenValidationParameters.RoleClaimType = "roles";
opt.TokenValidationParameters.NameClaimType = "name";

Related

.NET 5 Blazor Server OKTA Authentication showing HTTP Error 400

Using ASP.NET Core (.NET 5) Blazor Server with OKTA. OKTA log page has been prompted. I am getting below error messge on submitting OKTA uid/pwd
HTTP Error 400. The size of the request headers is too long.
My middleware is as like below, using an OpenId Connect.
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddOpenIdConnect(options =>
{
options.RemoteAuthenticationTimeout = TimeSpan.FromMinutes(30);
options.AuthenticationMethod = OpenIdConnectRedirectBehavior.RedirectGet;
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = configuration["Okta:Domain"] + "/oauth2/default";
options.RequireHttpsMetadata = true;
options.ClientId = configuration["Okta:ClientId"];
options.ClientSecret = configuration["Okta:ClientSecret"];
options.ResponseMode = OpenIdConnectResponseMode.FormPost;
options.ResponseType = OpenIdConnectResponseType.Code;
options.Scope.Add("offline_access");
options.UseTokenLifetime = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.AccessDeniedPath = "/Public/AccessDenied";
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");
// Describe how to map the user info we receive to user claims
options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
options.ClaimActions.MapJsonKey(ClaimTypes.GivenName, "given_name", "string");
options.ClaimActions.MapJsonKey(ClaimTypes.Name, "given_name", "string");
options.ClaimActions.MapJsonKey("LastName", "lastname", "string");
options.ClaimActions.MapJsonKey("FirstName", "firstname", "string");
options.ClaimActions.MapJsonKey(ClaimTypes.Email, "email", "string");
options.ClaimActions.MapJsonKey("Groups", "Groups", "string");
options.ClaimActions.MapJsonKey("membership_roles", "membership_roles", "string");
options.SaveTokens = true;
options.NonceCookie.SameSite = SameSiteMode.Unspecified;
options.CorrelationCookie.SameSite = SameSiteMode.Unspecified;
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "groups",
RequireSignedTokens = true,
ValidateIssuer = false
};
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, displayName: $"EPDOne_{GlobalVariables.LocalEnv.EnvironmentName}",
options =>
{
options.Cookie.Name = $"EPDOne_{ GlobalVariables.LocalEnv.EnvironmentName}";
options.Cookie.HttpOnly = false;
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.Cookie.IsEssential = true;
options.Events = new CookieAuthenticationEvents
{
// this event is fired everytime the cookie has been validated by the cookie middleware,
// so basically during every authenticated request
// the decryption of the cookie has already happened so we have access to the user claims
// and cookie properties - expiration, etc..
OnValidatePrincipal = context =>
{
// since our cookie lifetime is based on the access token one,
// check if we're more than halfway of the cookie lifetime
var now = DateTimeOffset.UtcNow;
TimeSpan timeElapsed = now.Subtract(DateTime.Now.AddDays(1));
TimeSpan timeRemaining = now.Subtract(DateTime.Now.AddDays(2));
if (context is not null)
{
if (context.Properties is not null && context.Properties.IssuedUtc is not null)
{
timeElapsed = now.Subtract(context.Properties.IssuedUtc.Value);
}
else
{
context.ShouldRenew = true;
}
if (context.Properties is not null && context.Properties.ExpiresUtc is not null)
{
timeRemaining = context.Properties.ExpiresUtc.Value.Subtract(now);
}
else
{
context.ShouldRenew = true;
}
}
if (timeElapsed > timeRemaining || context?.ShouldRenew == true)
{
context.ShouldRenew = true;
var identity = (ClaimsIdentity)context?.Principal?.Identity;
if (identity is not null && identity.IsAuthenticated)
{
string CurrentBaseAddress = CurrentURL(context.HttpContext);
string returnUrl = "";
if (string.IsNullOrEmpty(CurrentBaseAddress) == false)
{
returnUrl = "?returnUrl=" + CurrentBaseAddress;
}
context.Response.Redirect(GlobalVariables.OKTACallBackURI + $"/refresh{returnUrl}");
}
}
return Task.CompletedTask;
}
};
});
services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/");
//options.Conventions.AllowAnonymousToFolder("/Public");
}
);
As you can see above, I used OpenId in Startup.cs and application is prompting with OKTA credential dialog and after submitting uid/pwd, page behaves like in a loop and then shows the HTTP Error 400 message. Any clues here?
Philipp Grigoryev - Thanks for your time. I later noticed inside my .NET Core Startup.cs file below code.
app.UseAuthorization();
app.UseAuthorization();
The correct lines should be
app.UseAuthentication();
app.UseAuthorization();
So actually Authentication middleware itself not enabled and in hurry I was using 2 lines of enabling Authorization itself. After the mentioned correction, it works. Sorry to anyone who spent time on this. I am closing this query.

IdentityServer 4 WsFederation - How to get access token for calling API

I am using Identity Server 4 with the Ws-Federation plugin. Identity Server is configured to connect to Azure AD for authentication. Here is the relevant code from Identity Server project:
public void ConfigureServices(IServiceCollection services)
{
var rsaCertificate = new X509Certificate2("rsaCert.pfx", "1234");
services.AddRazorPages();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<User, IdentityRole>(options =>
{
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(2);
options.Lockout.MaxFailedAccessAttempts = 3;
})
.AddDefaultUI()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddUserStore<CustomUserStore>()
.AddUserManager<CustomUserManager>()
.AddDefaultTokenProviders();
services.AddTransient<IUserStore<User>, CustomUserStore>();
services.AddTransient<IEmailSender, EmailSender>();
var builder = services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
// see https://identityserver4.readthedocs.io/en/latest/topics/resources.html
options.EmitStaticAudienceClaim = true;
})
.AddSigningCredential(rsaCertificate)
.AddInMemoryIdentityResources(IdentityConfig.IdentityResources)
.AddInMemoryApiScopes(IdentityConfig.ApiScopes)
.AddInMemoryClients(IdentityConfig.Clients)
.AddAspNetIdentity<User>()
.AddWsFederationPlugin(options =>
{
options.Licensee = "Licensee";
options.LicenseKey = "LicenseKey";
})
.AddInMemoryRelyingParties(new List<RelyingParty>());
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
})
.AddWsFederation(options =>
{
options.Wtrealm = "Azure AD App Id";
options.MetadataAddress = "WSFed metadata URL from Azure AD App";
options.Events.OnSecurityTokenValidated = SecurityTokenValidated;
})
.AddCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(IdentityConfig.SessionTimeoutInMinutes);
options.SlidingExpiration = true;
options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None;
});
}
I have an API protected with JWT bearer authentication which is connected to the same Identity Server. The relevant code from the API (Please note that https://localhost:5001 is the address which the Identity Server is running in):
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "https://localhost:5001";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false
};
});
}
I have an MVC client as well which is connected to the same Identity Server. I was able to successfully authenticate users from the MVC client. Now, what I would like to do is to call a protected API endpoint in the API project from within the MVC client. I haven't found any way to get the access token necessary for calling the protected API. Relevant code from the MVC client:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.Cookie.Name = "aspnetcorewsfed";
options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None;
options.SlidingExpiration = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(Configuration.GetValue<int?>("SessionTimeoutInMinutes") ?? 15);
})
.AddWsFederation(options =>
{
options.MetadataAddress = "https://localhost:5001/wsfed"; // Address of the Identity Server
options.RequireHttpsMetadata = false;
options.Wtrealm = "mvc"; // ClientId registered in Identity Server
options.CallbackPath = "/";
options.SkipUnrecognizedRequests = true;
});
}
There's documentation on the Identity Server website that describes how to access protected APIs as seen here. But this is using OpenIdConnect. Since I am using WsFederation, I have no clue on how to get the access token or refresh token. Is token refresh impossible with WsFed?
Can anyone point me in the right direction on how to go about this?
Use OpenIdConnect in the MVC client instead of WsFed. Change the code in the MVC client's Startup.cs to the following:
services.AddAuthentication(options =>{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
}).AddCookie("Cookies").AddOpenIdConnect("oidc", options =>{
options.Authority = "https://localhost:5001";
options.ClientId = "mvc-openid";
options.ClientSecret = "secret";
options.ResponseType = "code";
options.SaveTokens = true;
});
The corresponding client registration in Identity Server should be:
new Client {
ClientId = "mvc-openid",
ClientSecrets = {
new Secret("secret".Sha256())
},
AllowedGrantTypes = GrantTypes.Code,
RedirectUris = {
"https://localhost:6001/signin-oidc"
},
AllowedScopes = new List < string > {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api"
}
}
https://localhost:5001 is the Identity Server address and https://localhost:6001 is the MVC client address.
The access token for accessing the API can be obtained like so:
var accessToken = await HttpContext.GetTokenAsync("access_token");

Auth0 + Swashbuckle .Net Core 2.2. Missing claims in jwt token when using SwaggerUI

I am making a ASP.Net Core WebApi which is authentication via Auth0. I am using Swagger and SwaggerUI and trying to authenticate from Swagger UI.
// Add authentication services
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect("Auth0", options =>
{
// Set the authority to your Auth0 domain
options.Authority = $"https://{Configuration["Auth0:Authority"]}";
// Configure the Auth0 Client ID and Client Secret
options.ClientId = Configuration["Auth0:ClientId"];
options.ClientSecret = Configuration["Auth0:ClientSecret"];
// Set response type to code
options.ResponseType = "code";
// Configure the scope
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("offline_access");
options.SaveTokens = true;
// Set the callback path, so Auth0 will call back to http://localhost:3000/callback
// Also ensure that you have added the URL as an Allowed Callback URL in your Auth0 dashboard
options.CallbackPath = new PathString("/callback");
// Configure the Claims Issuer to be Auth0
options.ClaimsIssuer = "Auth0";
// Saves tokens to the AuthenticationProperties
options.SaveTokens = true;
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = context =>
{
context.ProtocolMessage.SetParameter("audience", #"https://predictor-dev.api");
return Task.FromResult(0);
},
// handle the logout redirection
OnRedirectToIdentityProviderForSignOut = (context) =>
{
var logoutUri = $"https://{Configuration["Auth0:Authority"]}/v2/logout?client_id={Configuration["Auth0:ClientId"]}";
var postLogoutUri = context.Properties.RedirectUri;
if (!string.IsNullOrEmpty(postLogoutUri))
{
if (postLogoutUri.StartsWith("/"))
{
// transform to absolute
var request = context.Request;
postLogoutUri = request.Scheme + "://" + request.Host + request.PathBase + postLogoutUri;
}
logoutUri += $"&returnTo={ Uri.EscapeDataString(postLogoutUri)}";
}
context.Response.Redirect(logoutUri);
context.HandleResponse();
return Task.CompletedTask;
}
};
})
.AddJwtBearer(options =>
{
options.Authority = Configuration["Auth0:Authority"];
options.Audience = Configuration["Auth0:Audience"];
options.TokenValidationParameters = new TokenValidationParameters
{
RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/roles"
};
options.ClaimsIssuer = "Auth0";
});
services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigin",
builder =>
{
builder
.WithOrigins(Configuration["FrontendBaseUrl"])
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
});
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "Predictor API", Version = "v1" });
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
c.AddSecurityDefinition("oauth2", new OAuth2Scheme
{
Type = "oauth2",
Flow = "implicit",
AuthorizationUrl = $"{Configuration["Auth0:Authority"]}authorize?audience={Configuration["Auth0:Audience"]}",
Scopes = new Dictionary<string, string>
{
{ "read:books", "Access read book operations" },
{ "write:books", "Access write book operations" }
}
});
c.OperationFilter<SecurityRequirementsOperationFilter>();
});
Here is the token which is returned after authentication via SwaggerUI:
{
"iss": "my iss",
"sub": "my sub",
"aud": "my aud",
"iat": 1556002815,
"exp": 1556010015,
"azp": "azp",
"scope": "read:books"
}
The problem here is that token doesn't have openid and profile information.
I don't have any custom rules in Auth0 that could limit my scopes (I removed them totally).I tried different options, but I could not get any additional claims.
Is there any configuration in Swagger that I am missing?
Thank you.
You have to pass "openid" and "profile" scopes to extend your token with openid and profile information

HttpContext.User null with authenticated user?

So I'm working on a .net core 2 project which where we want to create a basic platform which we can use for our future projects. For the login we use Identity. We have it all setup, the user can succesfully login and the cookie gets set. For some reason once we call HttpContext.User this results in a null. I'm pretty sure it does find an identity, yet this identity is empty. We have checked the cookie and it is perfectly fine, it has it's token. We did add token authentication, but that should not interfere with the cookie system when it sets the cookie.
Below is the Startup.cs
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyIdentityDbContext>(options => options
.UseSqlServer("Data Source=PATH;Initial Catalog=DB;Persist Security Info=True;User ID=ID;Password=*******"));
services.AddSingleton<IJwtFactory, JwtFactory>();
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie();
services.AddIdentity<User, IdentityRole>(options =>
{
options.SignIn.RequireConfirmedEmail = true;
options.User.RequireUniqueEmail = false;
options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
})
.AddEntityFrameworkStores<MyIdentityDbContext>()
.AddDefaultTokenProviders();
services.Configure<IISOptions>(options =>
{
options.ForwardClientCertificate = false;
});
var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));
services.Configure<JwtIssuerOptions>(options =>
{
options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)];
options.SigningCredentials = new SigningCredentials(_signingKey, SecurityAlgorithms.HmacSha256);
});
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],
ValidateAudience = true,
ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],
ValidateIssuerSigningKey = true,
IssuerSigningKey = _signingKey,
RequireExpirationTime = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
services
.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.ClaimsIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
cfg.TokenValidationParameters = tokenValidationParameters;
cfg.SaveToken = true;
});
services.Configure<IdentityOptions>(options =>
{
// Password settings
options.Password.RequireDigit = true;
options.Password.RequiredLength = 8;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequireLowercase = true;
options.Password.RequiredUniqueChars = 6;
// Lockout settings
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
// User settings
options.User.RequireUniqueEmail = true;
});
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.LoginPath = "/Account/Login"; // If the LoginPath is not set here, ASP.NET Core will default to /Account/Login
options.LogoutPath = "/Account/Logout"; // If the LogoutPath is not set here, ASP.NET Core will default to /Account/Logout
options.AccessDeniedPath = "/Account/AccessDenied"; // If the AccessDeniedPath is not set here, ASP.NET Core will default to /Account/AccessDenied
options.SlidingExpiration = true;
options.Cookie = new CookieBuilder
{
HttpOnly = true,
Name = "MyAuthToken",
Path = "/",
SameSite = SameSiteMode.Lax,
SecurePolicy = CookieSecurePolicy.SameAsRequest
};
});
services.AddAuthorization(options =>
{
options.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("Employee"));
options.AddPolicy("OwnerOnly", policy => policy.RequireClaim("Owner"));
options.AddPolicy("AdminOnly", policy => policy.RequireClaim("Admin"));
options.AddPolicy("ModeratorOnly", policy => policy.RequireClaim("Moderator"));
});
services.AddTransient<IEmailSender, EmailSender>();
services.Configure<AuthMessageSenderOptions>(Configuration);
services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
}
Here is the code used in the controller to get the user:
User _user = await _userManager.GetUserAsync(HttpContext.User);
And the code we use to login the user:
var result = await _signInManager.PasswordSignInAsync(model.Email,
model.Password, true, false);
You wrote AddAuthentication two times, once for Cookie and once for JWT and override the defaults.
only use AddAuthentication once and add Cookie and JWT to it.
services.AddAuthentication(options =>
{
// set schema here
})
.AddCookie(config =>
{
//config cookie
})
.AddJwtBearer(config =>
{
//config jwt
});
Now that you have two authentication scheme, you must select which one you want to authenticate your request with
[Authorize(CookieAuthenticationDefaults.AuthenticationScheme)]
or
[Authorize(JwtBearerDefaults.AuthenticationScheme)]
or even both
[Authorize($"{CookieAuthenticationDefaults.AuthenticationScheme},{JwtBearerDefaults.AuthenticationScheme}")]

ASP.NET Authorize Filter Denies Access for User in Specified Role

In my ASP.NET Core 2.0 Application, I am stuck with an issue an Admin logged in User cannot access controller I used the Authorize Filter on [Authorize(Policy="AdminAlone")].
I confirmed that the user is in the "Administrators" role and added the policy in startup.cs but it redirects to an AccessDenied view when I try to access the controller.
I saw a similar problem on this link, but the solution didn't help me
Startup Class in MVC Client - ConfigureServices
services.AddMvc();
services.AddSession();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddAuthorization(options =>
{
options.AddPolicy("AdminAlone", policy => policy.RequireRole("Administrators"));
});
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddCookie("Cookies")
.AddOpenIdConnect("Bearer", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ClientId = "mvcWeb";
options.ClientSecret = "spring12345";
options.ResponseType = OidcConstants.ResponseTypes.CodeIdToken;
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("NuB.HospitalSearch");
options.Scope.Add("offline_access");
});
Web API ConfigureServices
var jwtSecurityTokenHandler = new JwtSecurityTokenHandler
{
InboundClaimTypeMap = new Dictionary<string, string>()
};
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(option =>
{
option.Audience = "NuB.HospitalSearch";
option.Authority = "http://localhost:5000";
option.RequireHttpsMetadata = false;
option.SecurityTokenValidators.Clear();
option.SecurityTokenValidators.Add(jwtSecurityTokenHandler);
option.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateAudience = true,
ValidAudience = "NuB.HospitalSearch",
ValidateIssuer = true
};
});
You may try the following. Inside your AddOpenIdConnect configuration add
options.TokenValidationParameters = new TokenValidationParameters {
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Role
};
In fact, this property defines the types and definitions required for validating a token. Please refer to this post from Dominick Baier for a more detailed explanation.