asp.net - 如何从 ASP.NET Web API 方法内部找到声明的内容?

标签 asp.net asp.net-web-api asp.net-identity claims-based-identity

在我的代码(ASP.NET Identity 2.1)中,我设置声明如下:

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
        ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
        if (user == null)
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return;
        }
        ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
           OAuthDefaults.AuthenticationType);
        ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
            CookieAuthenticationDefaults.AuthenticationType);
        AuthenticationProperties properties = CreateProperties(
            user.UserName,
            oAuthIdentity,
            user.FirstName,
            user.LastName,
            user.Organization);
        AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
        context.Validated(ticket);
        context.Request.Context.Authentication.SignIn(cookiesIdentity);
    }

这是 CreateProperites 方法,然后添加角色声明:

    public static AuthenticationProperties CreateProperties(
        string userName,
        ClaimsIdentity oAuthIdentity,
        string firstName,
        string lastName,
        int organization)
    {

        IDictionary<string, string> data = new Dictionary<string, string>
            {
                { "userName", userName},
                { "firstName", firstName},
                { "lastName", lastName},
                { "organization", organization.ToString()},
                { "roles",string.Join(":",oAuthIdentity.Claims.Where(c=> c.Type == ClaimTypes.Role).Select(c => c.Value).ToArray())}

            };
        return new AuthenticationProperties(data);
    }

在我的客户端上,我发出 token 请求并像这样接收它:

    this.$http({
        method: 'POST',
        url: '/Token',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
        },
        data: 'grant_type=password&username=' + encodeURIComponent(userName) + '&password=' + encodeURIComponent(password),
    })
        .success((data: any, status, headers, cfg) => {
            self.data.roles = data.roles;

我可以看到 self.data.roles 已正确填充角色。现在回到服务器,我想检查角色声明的内容。有人可以帮助告诉我该怎么做吗?我知道我可以在方法中执行以下操作:

    [HttpGet]
    [Route("Retrieve")]
    public async Task<IHttpActionResult> Retrieve()
    {

        var x = User;

x 获取

的值
System.Security.Claims.ClaimsPrinciple and 
System.Security.Claims.ClaimsIdentity

但是在 x 中我找不到有关声明本身的信息。

请注意,我确实尝试过之前在 SO 上发布的建议:

        var identity = (ClaimsIdentity)User.Identity;
        IEnumerable<Claim> claims = identity.Claims;

        // The following line returns null
        var roles = identity.Claims.Where(r => r.Type == "roles").FirstOrDefault();

但我仍然无法在声明中找到与角色声明相关的信息。我知道它到达客户手中时一定就在那里。

请注意,我正在专门寻找“角色”声明。不是任何系统生成的声明。但我自己尝试添加的那个包含角色的串联列表。

最佳答案

你尝试过这个吗?

var roleClaims = Identity.Claims.Where(c => c.Type == ClaimTypes.Role);

更新

首先,您没有添加声明。您正在将一些数据添加到 AuthenticationTicket 的属性字典中。该数据恰好是逗号分隔的角色,并且您选择命名的键是“roles”。因此,这不是一个主张。

当你说它对我不起作用时,我相信你想找到你放入字典中的逗号分隔值。如果是这种情况,您将无法从 Controller 中的 User 检索它。当您发送不记名 token 时,不记名 token 身份验证中间件会读取该 token ,从 token 中获取 ClaimsIdentity 并将其设置在上下文中,以便您可以从 User 读取它。

您放入 AuthenticationTicket 中的任何内容都可供中间件(实际上是处理程序)使用。因此,如果您想从 AuthenticationTicket 获取任何数据,您需要自己在承载中间件上调用 AuthenticateAsync 。通过执行 var result = wait AuthenticationManager.AuthenticateAsync(OAuthDefaults.AuthenticationType);,您现在将获得整个票证,而不仅仅是 ClaimsIdentity。通过查看结果,您应该能够获得逗号分隔的角色,但随后就会明白,承载中间件已经为您完成了一次,并且您正在再次调用它。

顺便说一句,如果您想添加自定义声明,则需要将其添加到 GrantResourceOwnerCredentials 中的 oAuthIdentity 中。

public override async Task GrantResourceOwnerCredentials(
                            OAuthGrantResourceOwnerCredentialsContext context)
{
    // snip
    ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
           OAuthDefaults.AuthenticationType);
    oAuthIdentity.AddClaim(new Claim("urn:roles", "a,b,c");
}

如果你这样做,你可以从User读取。

var myRoleClaims = Identity.Claims.Where(c => c.Type == "urn:roles");

关于asp.net - 如何从 ASP.NET Web API 方法内部找到声明的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26880640/

相关文章:

asp.net - 在 ASP.NET WebApi 中编写 CDATA

angular - .Net Core API CORS,只锁定一个域(Angular 应用程序)

.net - odata webapi 和 RESTier 之间的区别?

asp.net-mvc - Web API OData Controller 和授权属性

asp.net-identity - 如何在 MVC 6 API 中使用不记名 token ?

asp.net - 将 SCSS 文件打包成 CSS

asp.net - 我可以在 .aspx 页面中使用 ViewBag 吗?

c# - DbInitializer 失败,必须在根类型上配置 key

c# - 如何从 SQL Server 代理运行作业?

c# - .NET Core 3.1 Identity 在 Azure 上登录需要很长时间