【问题标题】:ASP.NET Core 1.0. Bearer Token, cannot access custom claimsASP.NET 核心 1.0。 Bearer Token,无法访问自定义声明
【发布时间】: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;
}

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

【问题讨论】:

    标签: authentication asp.net-core jwt bearer-token aspnet-contrib


    【解决方案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 你有机会确认设置目的地有效吗?
    猜你喜欢
    • 1970-01-01
    • 2021-07-18
    • 2019-11-23
    • 2017-10-22
    • 2019-07-21
    • 2019-06-29
    • 2017-02-07
    • 2020-02-10
    • 2021-08-06
    相关资源
    最近更新 更多