【问题标题】:AuthorizationFilterContext returns null on context.HttpContext.UserAuthorizationFilterContext 在 context.HttpContext.User 上返回 null
【发布时间】:2021-11-21 14:52:05
【问题描述】:

我有一个 RestrictedAttribute 来保护从 IAuthorizationFilter 实现 OnAuthorization(AuthorizationFilterContext context) 的控制器。

然后我需要检查用户是否使用以下代码进行了身份验证:

public void OnAuthorization(AuthorizationFilterContext context)
{
    IPrincipal user = context.HttpContext.User;
    
    // If the user is not authenticated...
    
    if (!user.Identity.IsAuthenticated)
    {
        TraceFailure("Unauthorized. User (principal identity) is not authenticated.", null);
    
        // Add to response HttpStatusCode.Unauthorized
    }
}

我所有的控制器都由我们的自定义 ApiBaseController 继承,它具有 [Restricted] 属性,例如:

/// <summary>
/// Defines the base class for all API controllers.
/// </summary>
[Restricted]
[DynamicClaims]
[CultureAware]
public abstract class ApiBaseController : ControllerBase

我向请求发送了一个有效令牌,但 user 的所有参数都为 null,并且 IsAuthenticated 始终为 false(因为是默认值)。

我配置了我的身份验证和授权,如下所示:

public static IServiceCollection AddIdentityClientMiddlewareService(
            this IServiceCollection services)
{
    try
    {
        services.AddAuthorization((options) =>
        {
            options.AddPolicy(
            "DefaultScope",
            (policy) =>
            {
                policy.AuthenticationSchemes = new List<string>
                {
                    "Bearer"
                };

                policy.RequireClaim("scope", Configuration.WebApiScopes);
            });
        }).AddAuthentication((options) => 
        {
            options.DefaultAuthenticateScheme = AuthorizationConstants.AuthenticationSchemes.Cookies;
            options.DefaultChallengeScheme = AuthorizationConstants.AuthenticationSchemes.Oidc;
        }).AddCookie(AuthorizationConstants.AuthenticationSchemes.Cookies, (options) =>
        {
            options.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest;
            options.CookieManager = new SameSiteCookieManager(new ChunkingCookieManager());
        }).AddOpenIdConnect(AuthorizationConstants.AuthenticationSchemes.Cookies, (options) =>
        {
            // Set the identity server endpoint

            options.Authority = Configuration.AuthorityEndpoint;

            // Set the authentication type

            // Set the grant used (hybrid)

            options.ResponseType = "code id_token token";

            // Set client id and client secret

            options.ClientId = Configuration.ClientId;
            options.ClientSecret = Configuration.ClientSecret;

            // Set the scopes requested

            options.Scope.Add(Configuration.WebUserInterfaceScopes);

            // Setup notifications from the middleware

            options.Events = new Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectEvents()
            {
                // Notified when the authentication fails

                OnAuthenticationFailed = OnAuthenticationFailedAsync,

                // Notified when the security token is received

                OnTokenResponseReceived = OnTokenResponseReceivedAsync,

                // Notified when the security token has been validated

                OnTokenValidated = OnSecurityTokenValidatedAsync,

                // Notified when an authorization code is received

                OnAuthorizationCodeReceived = OnAuthorizationCodeReceivedAsync,

                // Notified when a redirect to an identity provider is requested

                OnRedirectToIdentityProvider = OnRedirectToIdentityProviderAsync,

                // Notified when a protocol message is received

                OnMessageReceived = OnMessageReceivedAsync,
            };
        }).AddJwtBearer((options) =>
        {
            // Setup the bearer token authentication middleware
            // This middleware is for the Web API

            // Set the identity server endpoint

            options.Authority = Configuration.AuthorityEndpoint;
            options.SaveToken = true;
            options.RequireHttpsMetadata = false;
            options.IncludeErrorDetails = true;
            options.RefreshOnIssuerKeyNotFound = true;

            // Token validation options
            // Disable audience validation

            options.TokenValidationParameters = new TokenValidationParameters()
            {
                ValidateAudience = false,
                NameClaimType = "name",
                RoleClaimType = "role"
            };
        });
    }
    catch (Exception ex)
    {
        throw new InvalidOperationException("Unable to configure the Identity Server.", ex);
    }
        
    return services;
}

为什么我的context.HttpContext.User 没有填充元数据?我错过了什么?

【问题讨论】:

  • 您是否在端点上指定了正确的身份验证方案?正如我所看到的,您使用的默认身份验证方案是AuthorizationConstants.AuthenticationSchemes.Cookies,所以......如果端点只是由一个简单的[Authorize] 保护,那么当然,无论我们发送哪个 Jwt 令牌,它都是空的。
  • @GordonKhanhNg。我所有的控制器都是从我们的自定义 ApiBaseController 派生的,它具有 [Restricted] 属性。
  • 所以...我们还需要实现[Restricted]。重点是HttpContext.User 是身份验证流程的结果。如果我们的[Restricted] 属性实现与它有关(以及它的处理程序,如果有的话),那么我们可以追溯它,否则,问题仍然存在于我上面提到的身份验证方案问题。
  • @GordonKhanhNg。 [Restricted] 的实现是我的问题的第一个示例代码。

标签: c# asp.net-core authorization asp.net-identity .net-5


【解决方案1】:

嗯……过了好久回到迷宫……终于我发现了一些东西。

AddAuthentication 配置将AuthorizationConstants.AuthenticationSchemes.Cookies 确定为其默认身份验证方案(我想我们忘记更改AddOpenIdConnect 上的方案,因为它目前是Cookie 名称)。 DefaultChallengeScheme被指定为AuthorizationConstants.AuthenticationSchemes.Oidc,但如果请求没有被重定向,则证明它使用cookie身份验证来验证并传递下去。

a valid token 现在没有用了,因为我们没有指定端点上的特定身份验证方案。因此,它使用默认的cookie。

这是基于我们没有放弃 app.UseAuthentication(); app.UseAuthorization(); 的假设。

我敢打赌,将 defaultAuthentication 更改为正确的会解决问题

.AddAuthentication((options) => 
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = AuthorizationConstants.AuthenticationSchemes.Oidc;
        })

【讨论】:

    猜你喜欢
    • 2020-03-30
    • 1970-01-01
    • 2011-02-06
    • 2016-01-26
    • 2015-06-11
    • 2015-08-11
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多