Request.GetOwinContext()。获取<t>在APIControler中返回null

时间:2017-06-07 13:42:35

标签: c# asp.net-web-api2 token asp.net-apicontroller

我无法从通过令牌验证后存储的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");
    }
}

1 个答案:

答案 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)。客户端标识符应该是一个易于传输的小而唯一的字符串。