Asp.net core 使用OKTA OpenIdConnect进行基于策略的身份验证

Asp.net core 使用OKTA OpenIdConnect进行基于策略的身份验证,asp.net-core,openid-connect,okta,group-policy,Asp.net Core,Openid Connect,Okta,Group Policy,我有一个.net核心应用程序,它使用OpenIdConnect作为默认身份验证方案,并使用自定义授权服务器 services.AddAuthentication(authenticationOptions => { authenticationOptions.DefaultAuthenticateScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCo

我有一个.net核心应用程序,它使用OpenIdConnect作为默认身份验证方案,并使用自定义授权服务器

services.AddAuthentication(authenticationOptions =>
        {
            authenticationOptions.DefaultAuthenticateScheme = OpenIdConnectDefaults.AuthenticationScheme;
        })
        .AddCookie()
        .AddOpenIdConnect(openIdOptions =>
        {
            openIdOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            openIdOptions.Authority = issuer;
            openIdOptions.RequireHttpsMetadata = true;
            openIdOptions.ClientId = Configuration["Okta:ClientId"];
            openIdOptions.CallbackPath = OktaDefaults.CallbackPath;
            openIdOptions.ClientSecret = Configuration["Okta:ClientSecret"];
            openIdOptions.ResponseType = OpenIdConnectResponseType.Token;
            openIdOptions.GetClaimsFromUserInfoEndpoint = true;
            openIdOptions.Scope.Add("openid");
            openIdOptions.Scope.Add("profile");
            openIdOptions.Scope.Add("groups");
            openIdOptions.SaveTokens = true;
        });
我还使用基于策略的身份验证

services.AddAuthorization(authOptions =>{authOptions.AddPolicy(“QSGAdminPolicy”,policy => policy.RequireRole(Configuration.GetValue(“SecurityRoles:QSGAdminRole”)));
        authOptions.AddPolicy("QSGReadOnlyPolicy",
            policy => policy.RequireRole(Configuration.GetValue<string>("SecurityRoles:QSGReadOnlyRole")));

        authOptions.AddPolicy("QSGReviewerPolicy",
            policy => policy.RequireRole(Configuration.GetValue<string>("SecurityRoles:QSGReviewerRole"), Configuration.GetValue<string>("SecurityRoles:QSGTraderRole"), Configuration.GetValue<string>("SecurityRoles:.QSGAdminRole")));

        authOptions.AddPolicy("QSGTraderPolicy",
           policy => policy.RequireRole(Configuration.GetValue<string>("SecurityRoles:QSGTraderRole"), Configuration.GetValue<string>("SecurityRoles:QSGAdminRole")));
    });
但我得到了一个错误:

fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HLU51T84D7HA", Request id "0HLU51T84D7HA: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)
at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate) 
Microsoft.AspNetCore.Authorization.Infrastructure.RolesAuthorizationRequirement.
HandleRequirementAsync(Au  
thorizationHandlerContext context, RolesAuthorizationRequirement requirement)
at Microsoft.AspNetCore.Authorization.AuthorizationHandler`1.HandleAsync(AuthorizationHandlerContext 
context)
at 
Microsoft.AspNetCore.Authorization.Infrastructure.PassThroughAuthorizationHandler.
HandleAsync(AuthorizationHandlerContext context)
at Microsoft.AspNetCore.Authorization.DefaultAuthorizationService.AuthorizeAsync(ClaimsPrincipal 
user, Object resource, IEnumerable`1 requirements)
 at Microsoft.AspNetCore.Authorization.Policy.PolicyEvaluator.AuthorizeAsync(AuthorizationPolicy 
  policy, AuthenticateResult authenticationResult, HttpContext context, Object resource)
   at 
   Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter.
OnAuthorizationAsync(AuthorizationFilterContext 
 context)
 at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext] 
(IHttpApplication`1 application)
fail:Microsoft.AspNetCore.Server.Kestrel[13]
连接id“0HLU51T84D7HA”,请求id“0HLU51T84D7HA:0000000 1”:发生未处理的异常
由应用程序抛出。
System.ArgumentNullException:值不能为null。
参数名称:value
位于System.Security.Claims.ClaimsIdentity.HasClaim(字符串类型,字符串值)
位于System.Security.Claims.ClaimsPrincipal.IsInRole(字符串角色)
位于Microsoft.AspNetCore.Authorization.Infrastructure.RoleAuthorizationRequirement。
c_uuu显示类4_0.b_uu0(字符串r)
at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source,Func`2谓词)
Microsoft.AspNetCore.Authorization.Infrastructure.RolesAuthorization要求。
HandleRequirementAsync(Au)
授权处理上下文、角色授权要求)
位于Microsoft.AspNetCore.Authorization.AuthorizationHandler`1.HandleAsync(AuthorizationHandlerContext
(上下文)
在
Microsoft.AspNetCore.Authorization.Infrastructure.PassThroughAuthorizationHandler。
HandleAsync(授权HandlerContext上下文)
位于Microsoft.AspNetCore.Authorization.DefaultAuthorizationService.AuthorizationAsync(ClaimsPrincipal
用户、对象资源、IEnumerable`1需求)
位于Microsoft.AspNetCore.Authorization.Policy.PolicyEvaluator.authorizationAsync(AuthorizationPolicy
策略、AuthenticateResult authenticationResult、HttpContext上下文、对象资源)
在
Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter。
OnAuthorizationAsync(AuthorizationFilterContext
(上下文)
在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()中
在Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()上
位于Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext HttpContext)
位于Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext HttpContext)
在Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext上下文)中
位于Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext]
(IHTTP应用程序'1应用程序)
似乎它没有在团体声明中找到价值。如果我从控制器中删除策略并仅使用[Authorize],它将起作用,我将收到一个带有组声明的令牌
如何在身份验证时使用策略保护API?

请确保您在
appsettings.json中正确设置了角色:

"SecurityRoles": {
    "QSGReviewerRole": "QSGReviewerRole",
    "QSGTraderRole": "QSGTraderRole",
    "QSGAdminRole": "QSGAdminRole"
}
否则会发生错误,因为应用程序无法从配置中读取值。查看您的代码:

authOptions.AddPolicy("QSGReviewerPolicy",
        policy => policy.RequireRole(Configuration.GetValue<string>("SecurityRoles:QSGReviewerRole"), Configuration.GetValue<string>("SecurityRoles:QSGTraderRole"), Configuration.GetValue<string>("SecurityRoles:.QSGAdminRole")));
authOptions.AddPolicy(“qsgreeviewerpolicy”,
policy=>policy.RequireRole(Configuration.GetValue(“SecurityRoles:qsgreeviewerrole”)、Configuration.GetValue(“SecurityRoles:QSGTraderRole”)、Configuration.GetValue(“SecurityRoles:QSGAdminRole”);
请注意,您使用的是
SecurityRoles:.QSGAdminRole
。我认为应该是
SecurityRoles:QSGAdminRole

authOptions.AddPolicy("QSGReviewerPolicy",
        policy => policy.RequireRole(Configuration.GetValue<string>("SecurityRoles:QSGReviewerRole"), Configuration.GetValue<string>("SecurityRoles:QSGTraderRole"), Configuration.GetValue<string>("SecurityRoles:.QSGAdminRole")));