ASP.NET 核心 1.0。 Bearer Token,无法访问自定义声明

Posted

技术标签:

【中文标题】ASP.NET 核心 1.0。 Bearer Token,无法访问自定义声明【英文标题】:ASP.NET Core 1.0. Bearer Token, cannot access custom claims 【发布时间】:2016-05-04 10:50:14 【问题描述】:

我正在尝试使用 ASP.NET Core 1.0 为 SPA 设置承载身份验证。我几乎可以使用 OpenIdConnect Server 为 JwtToken 工作,但有一个问题是我的自定义声明没有随令牌一起返回。

我的 Startup.cs 身份验证逻辑如下:

private void ConfigureAuthentication(IApplicationBuilder app)

    app.UseJwtBearerAuthentication(options =>
    
        options.AutomaticAuthenticate = true;
        options.Authority = "http://localhost:53844";
        options.Audience = "http://localhost:53844";
        options.RequireHttpsMetadata = false;
    );

    app.UseOpenIdConnectServer(options =>
    
        options.TokenEndpointPath = "/api/v1/token";
        options.AllowInsecureHttp = true;
        options.AuthorizationEndpointPath = PathString.Empty;
        options.Provider = new OpenIdConnectServerProvider
        
            OnValidateClientAuthentication = context =>
            
                context.Skipped();
                return Task.FromResult<Object>(null);
            ,
            OnGrantResourceOwnerCredentials = async context =>
            
                var usersService = app.ApplicationServices.GetService<IUsersService>();

                User user = usersService.getUser(context.Username, context.Password);

                var identity = new ClaimsIdentity(new List<Claim>(), OpenIdConnectServerDefaults.AuthenticationScheme);
                identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()));
                identity.AddClaim(new Claim(ClaimTypes.Name, user.Id.ToString()));
                identity.AddClaim(new Claim("myclaim", "4815162342"));

                var ticket = new AuthenticationTicket(
                    new ClaimsPrincipal(identity),
                    new AuthenticationProperties(),
                    context.Options.AuthenticationScheme);

                ticket.SetResources(new[]  "http://localhost:53844" );
                ticket.SetAudiences(new [] "http://localhost:53844");
                ticket.SetScopes(new [] "email", "offline_access" );
                context.Validated(ticket);
            
        ;
    );

access_token 和 refresh_token 都生成成功,并且在 Authorization 标头系统中传递 access_token 时将请求视为已授权。

唯一的问题是除了 NameIdentifier 之外的所有声明都没有通过。

我使用以下代码接收我对经过身份验证的请求的声明:

public class WebUserContext : IUserContext

    private readonly IHttpContextAccessor contextAccessor;

    public WebUserContext(IHttpContextAccessor contextAccessor)
    
        this.contextAccessor = contextAccessor;
    

    public long UserId
    
        get
        
            ClaimsIdentity identity = Principal?.Identity as ClaimsIdentity;

            if (identity == null)
            
                return -1;
            

            Claim claim = identity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name); // There is no such claim in claims collection
            return long.Parse(claim.Value);
        
    

    private ClaimsPrincipal Principal => contextAccessor.HttpContext.User as ClaimsPrincipal;

我的声明未通过或未从令牌中提取的原因可能是什么?

【问题讨论】:

【参考方案1】:

我的声明未传递或未从令牌中提取的原因可能是什么?

安全性。

OAuthAuthorizationServerMiddleware 不同,ASOS 不假设访问令牌总是由您自己的资源服务器使用(尽管我同意这是一种常见情况)并且拒绝序列化未明确指定“目的地”的声明以避免泄漏机密数据给未经授权的各方。

由于 JWT 是 ASOS beta4 (but not in the next beta) 中的默认格式,您还必须记住,即使是客户端应用程序(或用户)也可以读取您的访问令牌。

因此,您必须在声明中明确附加一个“目的地”:

identity.AddClaim(ClaimTypes.Name, "Pinpoint", destination: "id_token token");

指定id_token 序列化身份令牌中的声明,指定token 序列化它在访问令牌中或两者都序列化它在两个令牌中(授权代码或刷新令牌没有等效项,因为它们始终是加密的并且只能由授权服务器本身读取)

【讨论】:

@lostaman 你有机会确认设置目的地有效吗?

以上是关于ASP.NET 核心 1.0。 Bearer Token,无法访问自定义声明的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET 5 OAuthBearerAuthentication:不接受以下身份验证方案:Bearer

uri查询参数中的asp.net核心JWT?

使用 ADFS 的 JWT Bearer 身份验证将 ASP.NET Framework 迁移到 ASP.NET Core 3.1

每当我发送包含 Bearer 令牌的请求时,ASP.Net Core API 总是返回 401 未授权

asp.net 核心 1.0 mvc。从 Request.Body 获取原始内容

ASP.Net Core 3.0 JWT Bearer Token 没有 SecurityTokenValidator 可用