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

时间:2020-08-01 20:53:08

标签: c# .net-core adal

我正在为我的.NET Core项目使用 Microsoft.AspNetCore.Authentication.JwtBearer System.IdentityModel.Tokens.Jwt 软件包。

有些受[Authorize]注释保护的控制器端点必须从请求中获取访问令牌。目前,我正在以这种方式在控制器方法中获取访问令牌:

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

并且我想知道是否有更好的“即用型”解决方案,因为使用上述代码在从不记名令牌中获取子字符串时仍然可能导致错误。

3 个答案:

答案 0 :(得分:4)

这是获取标题的聪明方法,而无需进入标题字典。这也将使框架解析令牌,这是我相信您正在寻找的令牌:

[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();
}

您也可以按照传统的方式获取标题:

[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();
}

AuthenticationHeaderValue.TryParse可以解决奇怪的情况,例如方案和令牌之间有多个空格,方案之前或令牌后面有空格...并对其进行修剪为您服务。

现在,这些情况永远都不会发生,但是...它们可能 ,并且执行accessTokenWithBearerPrefix.Substring("Bearer ".Length);会失败。这就是为什么我相信您想要解析令牌的更具体方法。

答案 1 :(得分:1)

您可以将 Startup.cs 中的SaveToken设置为true

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

并使用HttpContext方法从GetTokenAsync获取访问令牌。

using Microsoft.AspNetCore.Authentication;

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

答案 2 :(得分:0)

您可以使用以下代码获取安全令牌。

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

此外,如果您想Ignore 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;
}