it-swarm.com.de

Ansprüche von einem Web-API-Controller abrufen - JWT-Token,

Ich habe eine Anwendung erstellt, die die JWT-Trägerauthentifizierung in ASP.NET Core verwendet. Bei der Authentifizierung definiere ich einige benutzerdefinierte Ansprüche, die ich in einem anderen WebAPI-Controller lesen muss, um einige Aktionen auszuführen.

Irgendwelche Ideen Wie kann ich das erreichen?

So sieht mein Code aus: (Code wurde vereinfacht)

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

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

    }

Ein anderer Controller: (Er muss den Claim "verificationKey" lesen.)

    [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();
        }
    }
12
D.B

Sie sollten in der Lage sein, Ansprüche wie diesen in Ihrem Controller abzurufen

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

}

Wenn Sie möchten, können Sie Erweiterungsmethoden für die IPrincipal-Schnittstelle schreiben und Ansprüche mit dem obigen Code abrufen. Rufen Sie sie dann beispielsweise mit ab.

HttpContext.User.Identity.MethodName();

Zur Vollständigkeit der Antwort. Um das JWT-Token zu dekodieren, schreiben wir eine Methode, um das Token zu validieren und die Informationen zu extrahieren.

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

Jetzt können wir die Ansprüche validieren und extrahieren, indem wir Folgendes verwenden:

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

Sie sollten beachten, dass die ValidateToken-Methode den Wert null zurückgibt, wenn die Validierung fehlschlägt.

29
Adriani6
// 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's 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...
1
avg_bloke

Es gibt einige JWT-Implementierungen für .NET Framework. Wenn Sie System.IdentityModel.Tokens.Jwt verwenden, erhalten Sie bei der Validierung des Tokens eine System.Security. Claims.ClaimsPrincipal , das die Ansprüche des Tokens in seiner Eigenschaft "Claims" speichert. So können Sie die Ansprüche des Tokens wie folgt abrufen:

        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
        }

Wo platzieren Sie diesen Code? Meine Wahl war, die Tokenüberprüfung als Berechtigungsfilterattribut zu implementieren, das von AuthorizationFilterAttribute abgeleitet wurde. Wenn Sie einen Controller mit dem Attribut ausstatten, wird dessen OnAuthorization-Methode vor jedem Aufruf der Endpunkte des Controllers ausgeführt. Sie platzieren den obigen Code in der OnAuthorization-Methode und speichern den von der Tokenüberprüfung zurückgegebenen Principal in HttpContext.Current.User , auf das auch in jedem zugegriffen werden kann Endpunkt auf Ihrer API. http://blogs.quovantis.com/json-web-token-jwt-with-web-api/ ist ein gutes Beispiel für diese Implementierung.

0
GBU