Sam*_*tar 5 asp.net claims-based-identity asp.net-web-api asp.net-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);
}
Run Code Online (Sandbox Code Playgroud)
这是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);
}
Run Code Online (Sandbox Code Playgroud)
在我的客户端上,我发出一个令牌请求,然后像这样收到它:
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;
Run Code Online (Sandbox Code Playgroud)
我可以看到self.data.roles正确填充了角色.现在回到服务器上我想查看角色声明的内容.有人可以通过告诉我如何做到这一点来帮忙吗?我知道我可以在一个方法中执行以下操作:
[HttpGet]
[Route("Retrieve")]
public async Task<IHttpActionResult> Retrieve()
{
var x = User;
Run Code Online (Sandbox Code Playgroud)
x获取的值
System.Security.Claims.ClaimsPrinciple and
System.Security.Claims.ClaimsIdentity
Run Code Online (Sandbox Code Playgroud)
但在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();
Run Code Online (Sandbox Code Playgroud)
但我仍然无法在索赔内找到与角色声明相关的信息.我知道它必须在那里,因为它到达客户端.
请注意我正在寻找具体的"角色"声明.没有任何系统生成的声明.但是我试图添加自己的那个包含角色的连接列表.
你试过这个吗?
var roleClaims = identity.Claims.Where(c => c.Type == ClaimTypes.Role);
UPDATE
首先,您没有添加索赔.您正在将一些数据添加到的属性字典中 AuthenticationTicket.这些数据恰好是逗号分隔的角色,您选择命名的密钥是"角色".所以,这不是一个主张.
当你说它对我不起作用时,我相信你想找到你在字典中放入的逗号分隔值.如果是这种情况,则无法从User控制器中检索它.当您发送承载令牌时,承载令牌身份验证中间件会读取令牌,ClaimsIdentity从令牌获取并在上下文中设置该令牌,以便您可以将其读取User.
你放入的任何东西AuthenticationTicket都是用于中间件(实际上是处理程序)的.因此,如果您想从中获取任何数据AuthenticationTicket,您需要自己调用AuthenticateAsync承载中间件.通过这样做var result = await AuthenticationManager.AuthenticateAsync(OAuthDefaults.AuthenticationType);,你现在得到整个票,而不仅仅是ClaimsIdentity.通过查看result,您应该能够获得逗号分隔的角色,但随后了解,持有者中间件已经为您完成了一次,并且您再次调用它.
顺便说一句,如果你想添加一个自定义声明,那么你需要将它添加到oAuthIdentityin GrantResourceOwnerCredentials.
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");
}
Run Code Online (Sandbox Code Playgroud)
如果你这样做,你可以阅读User.
var myRoleClaims = identity.Claims.Where(c => c.Type == "urn:roles");
| 归档时间: |
|
| 查看次数: |
3055 次 |
| 最近记录: |