我无法从通过令牌验证后存储的OwinContext环境中检索数据。
这是守则:
[ValidateClientAuthentication]
在代码中,我验证用户的ClientID,然后在此行中将ApplicationClient的数据存储在OwinContext中
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
...
ApplicationClient App = new ApplicationClient();
App.Id = clientId;
App.ClientSecretHash = clientSecret;
// Storing Client Data
context.OwinContext.Set<ApplicationClient>("oauth:client", App);
context.Validated(clientId);
}
[GrantResourceOwnerCredentials] 在这里,我验证用户凭据并将令牌添加到令牌
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
...
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
if (Membership.ValidateUser(username, password))
{
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
identity.AddClaim(new Claim(ClaimTypes.Name, username));
context.Validated(identity);
}
else
{
context.SetError("Login Field", "Error username or password");
}
}
[ControlerCode]现在这是我的问题
[Authorize]
public class MyController : ApiController
{
public IEnumerable<SelectedMenu> GetAllMenus() // Resturants ID
{
// client is Null
ApplicationClient client = HttpContext.Current.GetOwinContext().Get<ApplicationClient>("oauth:client");
}
}
答案 0 :(得分:1)
您应该只在令牌中添加clientId
,这样您就可以在登录过程后随时检索它。
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
// ...
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
if (Membership.ValidateUser(username, password))
{
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
identity.AddClaim(new Claim(ClaimTypes.Name, username));
identity.AddClaim(new Claim("oauth-client", context.ClientId));
context.Validated(identity);
}
else
{
context.SetError("Login Field", "Error username or password");
}
}
您还可以创建一种扩展方法来帮助您检索clientId
:
public static class PrincipalExtensions
{
public static string GetClientId(this IPrincipal principal)
{
return (principal.Identity as ClaimsIdentity)?
.Claims
.FirstOrDefault(c => c.Type == "oauth-client")?
.Value;
}
}
在你的控制器内:
[Authorize]
public class MyController : ApiController
{
public IEnumerable<SelectedMenu> GetAllMenus() // Resturants ID
{
var clientId = User.GetClientId();
}
}
关于令牌大小:如果您的clientId
字符串太长,我建议您使用另一个字符串,并在数据库中存储任何其他客户端信息(如果需要,还包括更长的ID)。客户端标识符应该是一个易于传输的小而唯一的字符串。