Webapi get bearer token

Ale*_*ite 5 c# asp.net-web-api2

I'm practicing with asp.net webapi, and want to make separated authorization service.

So I implement authorization service based on tokens (owin), and data provider service. Now I want to override Authorize attribute in data provider service. It must take bearer token from current request, make request to authorization service, receive information about user and his roles.

The question is: how I can get bearer token in my custom attribute, and maybe there are better ways to make this "token transfer"?

I want to use it like this:

//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;
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*ite 0

正如布莱尔·艾伦(Blair Allen)悲伤的那样,有更好的方法来做我想做的事。使用 IdentityServer4 生成令牌并仅检查令牌签名,无需任何其他请求。我切换到net core,这是mvc客户端的解决方案:接收令牌并将其保存在cookie中。

[HttpPost]
public async Task<IActionResult> Login(LoginViewModel model)
{
    if(!ModelState.IsValid)
    {
        return View(model);
    }

    var tokenResult = await AuthService.LoginUserAsync(model.Email, model.Password);
    if(!tokenResult.IsSuccess)
    {
        ModelState.AddModelError("","Wrong email or password");
        return View(model);

    }

    Response.Cookies.Append("access_token", tokenResult.AccessToken, new CookieOptions(){
        HttpOnly = true,
        SameSite = SameSiteMode.Strict,
        Secure = true
    });

    return RedirectToAction("Index", "Home");

}
Run Code Online (Sandbox Code Playgroud)

然后只需使用

services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, config =>
{
    config.Authority = configuration["TokenServerUrl"];
    config.Events = new JwtBearerEvents
    {
        OnMessageReceived = context =>
        {
            var token = context.HttpContext.Request.Cookies["access_token"];
            context.Token = token;
            return Task.CompletedTask;

        },

    };
    config.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidIssuer = configuration["TokenServerUrl"],
        ValidateLifetime = true,
    };
});
Run Code Online (Sandbox Code Playgroud)