I have a simple web app API that I want to secure one API using Policy based authentication. I don’t know what I am doing wrong but it seems that it is looking for some claim. I followed exactly what was mentioned here
Here is the error I get:
(authentication works without policy)
Connection id "0HLU6IISDO6KV", Request id "0HLU6IISDO6KV:00000001": An unhandled
exception was thrown by the application.
System.ArgumentNullException: Value cannot be null.
Parameter name: value
at System.Security.Claims.ClaimsIdentity.HasClaim(String type, String value)
at System.Security.Claims.ClaimsPrincipal.IsInRole(String role)
at Microsoft.AspNetCore.Authorization.Infrastructure.RolesAuthorizationRequirement.
<>c__DisplayClass4_0.<HandleRequirementAsync>b__0(String r)
Here is what I have in my Startup.cs
services.AddAuthentication(authenticationOptions =>
{
authenticationOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
authenticationOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
authenticationOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(openIdOptions =>
{
openIdOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
openIdOptions.Authority = Configuration["Okta:Domain"];//issuer;
openIdOptions.ClientId = Configuration["Okta:ClientId"];
openIdOptions.CallbackPath = OktaDefaults.CallbackPath;
openIdOptions.ClientSecret = Configuration["Okta:ClientSecret"];
openIdOptions.ResponseType = OpenIdConnectResponseType.Code;
openIdOptions.GetClaimsFromUserInfoEndpoint = true;
openIdOptions.Scope.Add("openid");
openIdOptions.Scope.Add("profile");
openIdOptions.SaveTokens = true;
openIdOptions.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "groups",
};
});
services.AddSingleton<IOktaClient>
(
new OktaClient(new OktaClientConfiguration()
{
OktaDomain = Configuration["Okta:Domain"],
Token = Configuration["Okta:TokenAPI"]`
I have added policy authentication
services.AddAuthorization(authOptions =>
{
authOptions.AddPolicy("ReviewerPolicy",
policy =>
{
policy.RequireRole(Configuration.GetValue<string>("SecurityRoles:RevieweRole"));
});
Then I added the authorize tag to my controller with the policy
[Authorize(Policy = "ReviewerPolicy")]
public ActionResult<string> GetTestAuth()
{
var claims = HttpContext.User.Claims;
return "user allowed";
}