首页 > 解决方案 > Webapi 获取不记名令牌

问题描述

我正在使用 asp.net webapi 进行练习,并希望提供单独的授权服务。

所以我实现了基于令牌(owin)的授权服务和数据提供者服务。现在我想覆盖数据提供者服务中的 Authorize 属性。它必须从当前请求中获取不记名令牌,向授权服务发出请求,接收有关用户及其角色的信息。

问题是:如何在我的自定义属性中获取不记名令牌,也许有更好的方法来进行这种“令牌转移”?

我想像这样使用它:

//data service
[CustomAttribute (Roles = "admin")]
public IEnumerable<string> Get()
{
    return new string[] { "value1", "value2" };
}



public class CustomAttribute : System.Web.Mvc.AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext  context)
    {
        using (WebClient client = new WebClient())
        {
            string bearerToken;
            //somehow get token
            client.Headers.Add("Authorization", "Bearer " + bearerToken);
            string userinfo = client.DownloadString("authURL/GetUserInfo");
            CustomUser user = JsonConvert.DeserializeObject<CustomUser>(userinfo);
            if (!user.Roles == this.Roles)
            {
                    //return 401
            }
        } 
    }
}


// authorization service
public async Task<UserInfoResponse> GetUserInfo()
{ 
    var owinContext = HttpContext.Current.GetOwinContext();
    int userId = owinContext.Authentication.User.Identity.GetUserId<int>();
    var response = new UserInfoResponse()
    {
        UserId = userId.ToString(),
        Roles = await UserManager.GetRolesAsync(userId)
    }; 
    return response;
}

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

解决方案


要回答有关如何在请求的 Authorization 标头中访问不记名令牌的具体问题:

public class CustomAttribute : System.Web.Mvc.AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext context)
    {
        System.Net.Http.Headers.AuthenticationHeaderValue authorizationHeader = context.HttpContext.Request.Headers.Authorization;

        // Check that the Authorization header is present in the HTTP request and that it is in the
        // format of "Authorization: Bearer <token>"
        if ((authorizationHeader == null) || (authorizationHeader.Scheme.CompareTo("Bearer") != 0) || (String.IsNullOrEmpty(authorizationHeader.Parameter)))
        {
            // return HTTP 401 Unauthorized
        }

        using (WebClient client = new WebClient())
        {
            client.Headers.Add("Authorization", "Bearer " + authorizationHeader.Parameter);
            string userinfo = client.DownloadString("authURL/GetUserInfo");
            CustomUser user = JsonConvert.DeserializeObject<CustomUser>(userinfo);
            if (!user.Roles == this.Roles)
            {
                    // I recommend return HTTP 403 Forbidden here, not 401. At this point
                    // the request has been authenticated via the bearer token, but the
                    // authenticated client does not have sufficient roles to execute the
                    // request, so they are forbidden from doing so. HTTP 401 Unauthorized
                    // is a bit of a misnomer because the actual intention is to determine
                    // whether or not the request is authenticated. HTTP 401 also implies
                    // that the request should be tried again with credentials, but that
                    // has already been done!
            }
        } 
    }
}

可能有更好的方法来做你想做的事情,但我对 MVC 方面的事情以及你的应用程序的身份验证/授权工作流程了解不够,无法提供一个好的答案。至少这应该有助于知道在哪里可以找到授权属性中的标头值。


推荐阅读