0

.NET Core [Authorize]属性に頭を悩ませているだけです。外部JWT認証マイクロサービスで.NET Core Authorize属性?

有効な認証情報が提供されるとJWTが返される認証サービスが実行されています(例:authapi.com)。このJWTが返されると、JWTを検証し、それを示すメッセージを返します。

これで、いくつかのアクション/コントローラの承認が必要な別のWebAPIを作成しています(genericapi.comとしましょう)。アイデアは、JWTはgenericapiへのリクエストのヘッダーに渡され、次にそれらを有効にするためにauthapi.comに渡す必要があります。

私はポリシーを追加しようとしたが、それは本当に速い畳み込まれてしまった、と私はすべての許可がauthapiをヒットする必要がありますので、私はむしろちょうどデフォルト[Authorize]は、これをしなかっただろうと、すべてのものの上に[Authorize(Policy="TokenValid")]を書かなければなりませんでした。

ヘッダーからそのJWTを取得し、[Authorize]の標準動作としてauthapiに渡すにはどうすればよいですか?

注意:私はgenericapiのJWTで何もしたくない、すべての認証はauthapiで処理されます。

答えて

2

デフォルトのJwtBearerAuthenticationMiddlewareをカスタマイズすると、カスタムISecurityTokenValidatorが提供されます。あなたのユーザーIDが自動的にミドルウェアによって設定され、あなたがMVC内Authorize属性を使用し続けることがあります。

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

そして、あなたの起動クラスで:

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

あなたはさらに、このアプローチを改善する必要があるかもしれませんこの方法では、すべての検証をリモートエンドポイントに委任することで、必要なものを達成することができます。

1

genericapiJwtBearerAuthenticationを使用しないことを理解する限り、この場合、カスタム認証ミドルウェア(authapiにjwtを送信し、それを検証して現在のユーザーを設定)をgenericapiに書き込むことができます。次に、[Authorize]属性を使用してください。 https://stackoverflow.com/a/37415902/5426333

を見てカスタム認証ミドルウェアを書き込むには

しかし可能ならば、私はあなたの道を行くだろう。 genericapiにはJwtBearerAuthenticationを使用します。その後、他の検証を処理するためにOnTokenValidatedイベントを使用します。

 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

実際、あなたは私が後にしていたものを釘付けにしました。私はJwtBearerAuthenticationが何をしているのか誤解したと思います。私はもう一度それを実行して参照してください。 – SamBC