简体   繁体   English

从没有承载前缀的授权 header 中获取访问令牌

[英]Fetch access token from authorization header without bearer prefix

I'm using the Microsoft.AspNetCore.Authentication.JwtBearer and System.IdentityModel.Tokens.Jwt packages for my .NET Core project.我正在为我的 .NET 核心项目使用Microsoft.AspNetCore.Authentication.JwtBearerSystem.IdentityModel.Tokens.Jwt包。

There are some controller endpoints protected by the [Authorize] annotation that have to fetch the access token from the request.有一些受[Authorize]注释保护的 controller 端点必须从请求中获取访问令牌。 Currently I'm fetching the access token in my controller method this way:目前我正在以这种方式在我的 controller 方法中获取访问令牌:

string accessTokenWithBearerPrefix = Request.Headers[HeaderNames.Authorization];
string accessTokenWithoutBearerPrefix = accessTokenWithBearerPrefix.Substring("Bearer ".Length);

and I would like to know if there is a better "ready to use" solution for this because using the code above might still lead to errors while taking the substring from the bearer token.我想知道是否有更好的“即用型”解决方案,因为使用上面的代码在从不记名令牌中获取 substring 时仍可能导致错误。

Here is a clever way to get the header without having to go in to the headers dictionary.这是一种无需将 go 放入标题字典的巧妙方法即可获得 header。 This will also let the framework parse the token, which is what I believe you are looking for:这也将让框架解析令牌,这就是我相信您正在寻找的:

[HttpGet, Route("someEndpoint")]
public IActionResult SomeEndpoint([FromHeader] string authorization)
{

    if(AuthenticationHeaderValue.TryParse(authorization, out var headerValue))
    {
        // we have a valid AuthenticationHeaderValue that has the following details:

        var scheme = headerValue.Scheme;
        var parameter = headerValue.Parameter;

        // scheme will be "Bearer"
        // parmameter will be the token itself.
    }

    return Ok();
}

You can also grab the header the old-school way:您也可以用老式的方式获取 header:

[HttpGet, Route("someEndpoint")]
public IActionResult SomeEndpoint()
{
    var authorization = Request.Headers[HeaderNames.Authorization];

    if (AuthenticationHeaderValue.TryParse(authorization, out var headerValue))
    {
        // we have a valid AuthenticationHeaderValue that has the following details:

        var scheme = headerValue.Scheme;
        var parameter = headerValue.Parameter;

        // scheme will be "Bearer"
        // parmameter will be the token itself.
    }

    return Ok();
}

What's nice is AuthenticationHeaderValue.TryParse will cover oddball cases like if there is more than once space between the scheme and the token, or if there are spaces before the scheme, or spaces after the token... and trim it up for you.好的是AuthenticationHeaderValue.TryParse将涵盖奇怪的情况,例如方案和令牌之间是否有多个空格,或者方案之前有空格,或者令牌之后有空格......并为您修剪它。

Now, those cases should never happen, but... they may , and the execution of accessTokenWithBearerPrefix.Substring("Bearer ".Length);现在,这些情况永远不会发生,但是......它们可能会,并且accessTokenWithBearerPrefix.Substring("Bearer ".Length);的执行would fail.会失败。 Which is why I believe you wanted a more concrete way of parsing the token.这就是为什么我相信您想要一种更具体的方式来解析令牌。

You can set SaveToken in Startup.cs to true .您可以将Startup.cs中的 SaveToken 设置为true

services.AddAuthentication()
    .AddJwtBearer(options =>
    {
        // your other config
        options.SaveToken = true;
    });

and get access token from HttpContext with GetTokenAsync method.并使用GetTokenAsync方法从HttpContext获取访问令牌。

using Microsoft.AspNetCore.Authentication;

public class SampleController : Controller
{
    public void Index()
    {
        var accessToken = HttpContext.GetTokenAsync("access_token");
    }
}

You can use the following code to get security token.您可以使用以下代码获取安全令牌。

var stream ="[encoded jwt]";  
var handler = new JwtSecurityTokenHandler();
var jsonToken = handler.ReadToken(stream);
var tokenS = handler.ReadToken(stream) as JwtSecurityToken;

Also, if you want to Ignore JWT Bearer token signature , you can refer to the code as below:另外,如果你想忽略 JWT Bearer token signature ,你可以参考下面的代码:

public TokenValidationParameters CreateTokenValidationParameters()
{
    var result = new TokenValidationParameters
    {
    ValidateIssuer = false,
    ValidIssuer = ValidIssuer,

    ValidateAudience = false,
    ValidAudience = ValidAudience,

    ValidateIssuerSigningKey = false,
    //IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SecretKey)),
    //comment this and add this line to fool the validation logic
    SignatureValidator = delegate(string token, TokenValidationParameters parameters)
    {
        var jwt = new JwtSecurityToken(token);

        return jwt;
    },

    RequireExpirationTime = true,
    ValidateLifetime = true,

    ClockSkew = TimeSpan.Zero,
    };

    result.RequireSignedTokens = false;

    return result;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM