Получить токен доступа из заголовка авторизации без префикса носителя - PullRequest
2 голосов
/ 01 августа 2020

Я использую пакеты Microsoft.AspNetCore.Authentication.JwtBearer и System.IdentityModel.Tokens.Jwt для моего. NET Core проекта.

Есть некоторые конечные точки контроллера, защищенные аннотацией [Authorize], которые должны извлекать токен доступа из запроса. В настоящее время я получаю токен доступа в своем методе контроллера следующим образом:

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

, и я хотел бы знать, есть ли для этого более "готовое к использованию" решение, потому что использование приведенного выше кода все еще может привести к ошибкам при взятии подстроки из токена-носителя.

Ответы [ 3 ]

1 голос
/ 08 августа 2020

Вот умный способ получить заголовок без необходимости go в словаре заголовков. Это также позволит фреймворку проанализировать токен, который, как я полагаю, вы ищете:

[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 голос
/ 09 августа 2020

Вы можете установить SaveToken в Startup.cs на 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");
    }
}
0 голосов
/ 04 августа 2020

Вы можете использовать следующий код для получения токена безопасности.

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

Кроме того, если вы хотите игнорировать подпись токена на предъявителя JWT , вы можете использовать следующий код:

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