APIControler 中的 Request.GetOwinContext().Get<T> return null
Request.GetOwinContext().Get<T> return null in APIControler
我无法从 OwinContext 环境中检索我在通过令牌验证后存储的数据。
这是代码:
[验证客户端身份验证]
在代码中,我验证了用户的 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");
}
}
您真的应该只在您的令牌中添加 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)存储在数据库中。客户端标识符应该是一个小而独特的字符串,易于传输。
我无法从 OwinContext 环境中检索我在通过令牌验证后存储的数据。
这是代码:
[验证客户端身份验证]
在代码中,我验证了用户的 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");
}
}
您真的应该只在您的令牌中添加 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)存储在数据库中。客户端标识符应该是一个小而独特的字符串,易于传输。