C# 从授权头中提取访问令牌,不带承载前缀

C# 从授权头中提取访问令牌,不带承载前缀,c#,.net-core,adal,C#,.net Core,Adal,我正在使用Microsoft.AspNetCore.Authentication.JwtBearer和System.IdentityModel.Tokens.Jwt包来完成.NET核心项目 有一些受[Authorize]注释保护的控制器端点必须从请求中获取访问令牌。目前,我正在通过以下方式获取控制器方法中的访问令牌: string accessTokenWithBearerPrefix = Request.Headers[HeaderNames.Authorization]; string ac

我正在使用Microsoft.AspNetCore.Authentication.JwtBearer和System.IdentityModel.Tokens.Jwt包来完成.NET核心项目

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

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

我想知道是否有更好的“随时可用”解决方案,因为在从承载令牌获取子字符串时,使用上述代码仍可能导致错误。

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

var stream ="[encoded jwt]";  
var handler = new JwtSecurityTokenHandler();
var jsonToken = handler.ReadToken(stream);
var tokenS = handler.ReadToken(stream) as JwtSecurityToken;
此外,如果您愿意,可以参考以下代码:

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;
}

下面是一个获取标题的聪明方法,无需进入headers字典。这还将允许框架解析令牌,我相信您正在寻找令牌:

[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”)将失败。这就是为什么我认为您需要一种更具体的方法来解析令牌。

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

services.AddAuthentication()
    .AddJwtBearer(options =>
    {
        // your other config
        options.SaveToken = true;
    });
并使用
GetTokenAsync
方法从
HttpContext
获取访问令牌

using Microsoft.AspNetCore.Authentication;

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

您可以看看asp net核心代码。是开源吗?你能解释一下这句话吗<代码>变量流=“[encoded jwt]”编码令牌来自何处?它是否来自
Request.Headers[HeaderNames.Authorization]
?它是没有承载前缀的完全访问令牌吗?它是没有承载前缀的完全访问令牌。从这里开始
Request.Headers[HeaderNames.Authorization]
?是的,删除承载前缀。也许我误解了您的解决方案,但我正在寻找一种方法,从访问令牌中删除承载前缀,而不必自己做。我尝试了你的代码,但不幸的是我得到了一个例外,我添加了它作为一个评论