.net Web API。如何从访问令牌中检索用户属性(用户 ID)?基于当前用户/令牌的请求处理程序代码

Posted

技术标签:

【中文标题】.net Web API。如何从访问令牌中检索用户属性(用户 ID)?基于当前用户/令牌的请求处理程序代码【英文标题】:.net Web API. How to retrieve user properties (user Id) from access token? Request handler code based on current user/token 【发布时间】:2015-02-28 10:23:12 【问题描述】:

假设您有一个用于基于用户的应用程序的 .net Web API 服务器。用户使用用户名和密码登录应用程序,该用户名和密码被发送到服务器,应用程序被返回一个访问令牌。

现在应用想要显示一些用户信息(存储在服务器上的数据库中)。因此,它向服务器发出 http 请求,并在标头中包含访问令牌。

您如何限制服务器只将特定用户的相关信息发送回应用程序,而不会发送其他人的信息。

当我收到他们的用户名和密码并创建要发回的令牌时,有没有办法将他们的 userId 与该令牌相关联?因此,现在当我收到对 /GetUserFoodPreferences 之类的请求时,我可以从令牌中获取 userId 并根据该 id 查询我的数据库。

这是正确的方法吗?

【问题讨论】:

【参考方案1】:

在 cookie 中存储用户 ID 或与该用户相关的其他类型的 ID 是最常见的方式。然后,您可以检查该 cookie (Request.Cookies["name"];) 的 id 以确认用户。

编辑:当然,如果您正在使用 API 控制器并正确验证您的用户,您可以使用:

HttpContext.Current.User.Identity.GetUserId();

注意:不要忘记import Microsoft.AspNet.Identity library。

【讨论】:

GetUserId() 是您自己编写的一些自定义方法吗?我看到 IIDentity 有 AuthenticationType、IsAuthenticated 和 Name。 你是如何验证用户的? get id 方法作为 MVC 的一部分出现在以下库 Microsoft.AspNet.Identity 中,但值得检查您使用的身份验证提供程序/方法。 是的,当我导入 Microsoft.AspNet.Identity 时,该方法有效。 我只是使用web api项目自带的默认认证。【参考方案2】:

试试这个:

在你的项目中,转到Providers/ApplicationOAuthProvider.cs,搜索方法public override Task TokenEndpoint(OAuthTokenEndpointContext context),并在foreach之后添加这一行:

context.AdditionalResponseParameters.Add ("userID" context.Identity.GetUserId());

您的代码如下所示:

public override Task TokenEndpoint(OAuthTokenEndpointContext context)

    foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
    
        context.AdditionalResponseParameters.Add(property.Key, property.Value);
    

    context.AdditionalResponseParameters.Add("userID",context.Identity.GetUserId());

    return Task.FromResult<object>(null);

【讨论】:

添加后如何从令牌中检索?【参考方案3】:

我有一个类似的问题,我通过创建自定义 OAuthProvider 来解决。

public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider

    private readonly IYourLoginLogic _loginLogic;

    /// <summary>
    /// Constructor
    /// </summary>
    public ApplicationOAuthProvider(IYourLoginLogic loginLogic)
    
        _loginLogic = loginLogic;
    

    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    
        context.Validated();
        return Task.FromResult<object>(null);
    

    /// <summary>
    /// Login the user with username and password.
    /// </summary>
    /// <param name="context">OAuthGrantResourceOwnerCredentialsContext</param>
    /// <returns>Not used</returns>
    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    
        bool loginRst = _loginLogic.Login(context.UserName, context.Password);

        if(!loginRst)
        
            context.SetError("invalid_grant", "The user name or password is incorrect.");
        
        else
        
            var identity = new ClaimsIdentity(context.Options.AuthenticationType);
            identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
            identity.AddClaim(new Claim("role", "user"));
            context.Validated(identity);
        

        return Task.FromResult<object>(null);
    

这样,用户名将包含在返回给客户端的令牌中。当客户端使用令牌发回请求时,您可以从请求的上下文中获取用户名,如下所示:

public class CustomizedAuthorizeAttribute : AuthorizeAttribute

    public override void OnAuthorization(HttpActionContext actionContext)
    
        base.OnAuthorization(actionContext);

        string username = actionContext.RequestContext.Principal.Identity.Name;
        // do something with the username
    

您需要为要保护的控制器或操作使用 CustomizedAuthrize 属性。

就我而言,它是这样的:

[CustomizedAuthorize]
public sealed class MyController : ApiController ......

【讨论】:

以上是关于.net Web API。如何从访问令牌中检索用户属性(用户 ID)?基于当前用户/令牌的请求处理程序代码的主要内容,如果未能解决你的问题,请参考以下文章

如何从当前用户检索(Jwt)访问令牌并将其传递给 asp.net 样板(abp)中的移动应用程序?

如何从 ASP.NET Core 中的密码重置令牌中检索用户?

如何使用 JWT 令牌在 .NET Core API 中检索当前用户数据?

如何通过 AngularJS $http 从 ASP.Net Web API 2 获取访问令牌?

在我的 ASP.NET Web API 中验证访问令牌

在 AAD 保护的 Azure Web 应用程序中检索访问令牌