0

So habe ich nur ein bisschen Mühe, meinen Kopf um das .NET Core [Authorize] -Attribut zu bekommen..NET Core Authorize-Attribut mit externem JWT-Authentifizierungs-Microservice?

Ich habe einen Authentifizierungsdienst ausgeführt (sagen wir authapi.com), der, wenn mit gültigen Authentifizierungsdetails versehen wird, eine JWT zurückgibt. Wenn diese JWT an sie zurückgegeben wird, validiert sie die JWT und gibt eine Nachricht zurück, die dies angibt.

Also, ich baue jetzt eine andere WebAPI (sagen wir genericapi.com), die Autorisierung für einige der Aktionen/Controller erfordert. Die Idee ist, dass der JWT in den Headern der Anfrage an genericapi übergeben wird, die dann diese an authapi.com weiterleiten muss, um sie zu validieren.

Ich habe versucht, eine Politik hinzugefügt aber es wurde sehr schnell gefaltet, und ich hatte [Authorize(Policy="TokenValid")] auf alles zu schreiben, wenn ich würde lieber nur die Standard-[Authorize] dies tat, da wird ALL Genehmigung authapi getroffen haben.

Wie würde ich gehen, um diese JWT aus der Kopfzeile und übergibt es an die authapi als Standardverhalten für [Authorize]?

Bedenken Sie: Ich möchte nichts mit den JWTs auf genericapi tun, alle Authentifizierung wird von authapi behandelt werden.

Antwort

2

Sie können versuchen, die Standardeinstellung JwtBearerAuthenticationMiddleware anzupassen, indem Sie eine benutzerdefinierte ISecurityTokenValidator bereitstellen. Ihre Benutzeridentität durch die Middleware wird, automatisch eingestellt und Sie können mit dem Authorize Attribut innerhalb MVC weiter:

class MyTokenValidator : ISecurityTokenValidator 
{ 
    public string AuthenticationScheme { get; } 

    public MyTokenValidator(string authenticationScheme) 
    { 
     AuthenticationScheme = authenticationScheme; 
    } 

    public bool CanValidateToken => true; 

    public int MaximumTokenSizeInBytes 
    { 
     get 
     { 
      throw new NotImplementedException(); 
     } 
     set 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    public bool CanReadToken(string securityToken) => true; 

    public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken) 
    { 
     validatedToken = null; 

     //your logic here 
     var response = GetResponseFromMyAuthServer(securityToken); 
     //assuming response will contain info about the user 

     if(response == null || response.IsError) 
      throw new SecurityTokenException("invalid"); 

     //create your identity by generating its claims 
     var claims = new[] 
     { 
      new Claim(ClaimTypes.NameIdentifier, response.UserId), 
      new Claim(ClaimTypes.Email, response.Email), 
      new Claim(ClaimsIdentity.DefaultNameClaimType, response.UserName), 
     }; 

     return new ClaimsPrincipal(new ClaimsIdentity(claims, AuthenticationScheme)); 
    } 
} 

Und in Ihrer Startklasse:

var options = new JwtBearerOptions(); 
options.SecurityTokenValidators.Clear(); 
options.SecurityTokenValidators.Add(new MyTokenValidator(options.AuthenticationScheme)); 

app.UseJwtBearerAuthentication(options); 

//the rest of your code here 
app.UseMvc(); 

Möglicherweise müssen Sie diesen Ansatz weiter verfeinern Auf diese Weise können Sie erreichen, was Sie benötigen, indem Sie die gesamte Validierung an den Remote-Endpunkt delegieren.

1

Soweit ich verstehe, möchten Sie nicht JwtBearerAuthentication in genericapi verwenden. In diesem Fall können Sie eine benutzerdefinierte Authentifizierungs-Middleware schreiben (senden Sie jwt an authapi und validieren Sie sie und setzen Sie dann den aktuellen Benutzer) für genericapi. Dann verwenden Sie einfach [Authorize] Attribut.

Um die benutzerdefinierte Authentifizierung Middleware zu sehen https://stackoverflow.com/a/37415902/5426333

jedoch wenn möglich zu schreiben, ich nicht mit dem Weg gehen würde. Ich würde JwtBearerAuthentication für genericapi verwenden. Dann würde ich OnTokenValidated Ereignis verwenden, um andere Validierungen zu behandeln.

 app.UseJwtBearerAuthentication(new JwtBearerOptions() 
     { 
      Events = new JwtBearerEvents() 
      { 
       OnTokenValidated = (context) => 
       { 
        // send jwt to auth api 
        // validate it 
        if (!valid) 
        { 
         context.SkipToNextMiddleware(); 
        } 
        return Task.FromResult(0); 
       } 
      } 
     }); 
+0

Eigentlich haben Sie ziemlich genagelt, was ich suchte, ich glaube, ich falsch interpretiert, was JWtBearerAuthentication tut. Ich werde es jetzt noch einmal durchgehen und sehen. – SamBC