Получите заявки от контроллера WebAPI - токена JWT,

Я создал приложение, которое использует аутентификацию на предъявителя JWT в ASP.NET Core. При аутентификации я определяю некоторые пользовательские требования, которые мне нужно прочитать в другом контроллере WebAPI, чтобы выполнить некоторые действия.

Любые идеи Как я могу это достичь?

Это выглядит как мой код: (код был упрощен)

public async Task<IActionResult> AuthenticateAsync([FromBody] UserModel user)
    {
        ..............

                var tokenHandler = new JwtSecurityTokenHandler();
                var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
                var tokenDescriptor = new SecurityTokenDescriptor
                {
                    Subject = new ClaimsIdentity(new Claim[]
                    {
                        new Claim("userSecurityKey", userDeserialized.SecurityKey.ToString()),
                        new Claim("timeStamp",timeStamp),
                        new Claim("verificationKey",userDeserialized.VerificationKey.ToString())

                    }),
                    Expires = DateTime.UtcNow.AddDays(7),
                    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),
                        SecurityAlgorithms.HmacSha256Signature)
                };
                var token = tokenHandler.CreateToken(tokenDescriptor);
                var tokenString = tokenHandler.WriteToken(token);

     .................                           

    }

Другой контроллер: (Требуется прочитать требование "проверкаKey").

    [HttpGet]
    [Route("getcandidate")]
    public async Task<IActionResult> GetCandidateAsync()
    {

        try
        {
             ............    


            var verificationKey = //TODO: GET VerificationKey FROM THE TOKEN

            var verificationRecord = await service.GetVerificationRecordAsync(verificationKey);

            .................

        }
        catch (Exception)
        {
            return NotFound();
        }
    }

Ответы

Ответ 1

Вы должны иметь возможность получить такие претензии в контроллере

var identity = HttpContext.User.Identity as ClaimsIdentity;
if (identity != null)
{
    IEnumerable<Claim> claims = identity.Claims; 
    // or
    identity.FindFirst("ClaimName").Value;

}

Если вы хотите, вы можете написать методы расширения для интерфейса IPrincipal и получить заявки, используя приведенный выше код, а затем получить их, используя (например)

HttpContext.User.Identity.MethodName();

Для полноты ответа. Чтобы декодировать токен JWT, напишите метод проверки токена и извлечения информации.

public static ClaimsPrincipal ValidateToken(string jwtToken)
    {
        IdentityModelEventSource.ShowPII = true;

        SecurityToken validatedToken;
        TokenValidationParameters validationParameters = new TokenValidationParameters();

        validationParameters.ValidateLifetime = true;

        validationParameters.ValidAudience = _audience.ToLower();
        validationParameters.ValidIssuer = _issuer.ToLower();
        validationParameters.IssuerSigningKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(_appSettings.Secret));

        ClaimsPrincipal principal = new JwtSecurityTokenHandler().ValidateToken(jwtToken, validationParameters, out validatedToken);


        return principal;
    }

Теперь мы можем проверить и извлечь претензии, используя:

ValidateToken(tokenString)?.FindFirst("ClaimName")?.Value

Следует отметить, что метод ValidateToken вернет null значение, если проверка не удалась.

Ответ 2

// Cast to ClaimsIdentity.
var identity = HttpContext.User.Identity as ClaimsIdentity;

// Gets list of claims.
IEnumerable<Claim> claim = identity.Claims; 

// Gets name from claims. Generally it an email address.
var usernameClaim = claim
    .Where(x => x.Type == ClaimTypes.Name)
    .FirstOrDefault();

// Finds user.
var userName = await _userManager
    .FindByNameAsync(usernameClaim.Value);

if (userName == null)
{
    return BadRequest();
}

// The rest of your code goes here...

Ответ 3

Существует несколько реализаций JWT для.NET Framework. Если вы используете System.IdentityModel.Tokens.Jwt, когда вы проверяете токен, вы получаете System.Security.Claims.ClaimsPrincipal, в котором хранятся заявки на токены в свойстве "Претензии". Таким образом, вы можете получить претензии на токен следующим образом:

        string token = // ... read the token
        JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
        TokenValidationParameters validationParameters = ...;
        SecurityToken securityToken;
        IPrincipal principal;
        try
        {
            // token validation
            principal = tokenHandler.ValidateToken(token, validationParameters, out securityToken);
            // Reading the "verificationKey" claim value:
            var vk = principal.Claims.SingleOrDefault(c => c.Type == "verificationKey").Value; 
        }
        catch
        {
            principal = null; // token validation error
        }

Теперь, где вы размещаете этот код? Мой выбор состоял в том, чтобы реализовать проверку маркера в качестве атрибута фильтра авторизации, полученного из AuthorizationFilterAttribute. Если вы украшаете контроллер атрибутом, его метод OnAuthorization выполняется перед каждым вызовом конечных точек контроллера. Вы помещаете вышеуказанный код в метод OnAuthorization и сохраняете принципала, возвращаемого проверкой маркера на HttpContext.Current.User, который также доступен на любой конечной точке вашего API. http://blogs.quovantis.com/json-web-token-jwt-with-web-api/ - хороший образец этой реализации.

Ответ 4

В любом контроллере net core 2, прошедшем авторизацию по схеме JwtBearerDefaults, вы можете использовать:

 [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
 public ActionResult Index()
    {
        var user = User.FindFirst("Name").Value;
        //or if u want the list of claims
        var claims = User.Claims;

        return View();
    }