2016-05-06 4 views
0

.Net Web APIを使用してC#でJWTの作成と使用の実装を記述するmany resourcesがあります。しかし私は現在のシステムをリストされたチュートリアルのいずれかに適合させるのに苦労しています。別のサービスを呼び出すことによってJWTを使用する

私はこの時点までそのようなクエリ文字列の一部として私のJWTトークンを送信してきた

:?

.../API /ユーザーJWT = aladsfjknasdfnjkladfskjlnajknjknfdsalnjksdfnjldf

と私のルート

public async Task<IHttpActionResult> GetUsers(string jwt) 
{ 
     var userValidationResult = await Utility.ValidateUser(jwt); 

     if (!userValidationResult.Validated) 
     { 
      return Unauthorized(); 
     } 

     ... 
} 

あなたは以下のことを検証ユーザメソッドの内容を表示することができます。このようになります。私は実際にJWTを認証のために別のサーバーに送信することによってJWTを検証することに注意してください。

public class UserValidationResult 
    { 
     public bool Validated { get; set; } 
     public string Email { get; set; } 
     public List<string> Roles { get; set; } 
    } 

    public static Task<UserValidationResult> ValidateUser(string jwt) 
    { 
     var taskCompletionSource = new TaskCompletionSource<UserValidationResult>(); 

     var authenticationRoute = "http://authserver:5000/authenticate?jwt=" +jwt; 
     var authenticationClient = new RestClient(authenticationRoute); 
     var authenticationRequest = new RestRequest(Method.GET); 

     authenticationClient.ExecuteAsync(authenticationRequest, authenticationResponse => 
     { 
      var authenticationResponseInJson = JObject.Parse(authenticationResponse.Content.ToString()); 
      var payload = JObject.Parse(authenticationResponseInJson["payload"].ToString()); 

      taskCompletionSource.SetResult(new UserValidationResult() 
      { 
       Validated = bool.Parse(authenticationResponseInJson["success"].ToString()), 
       Email = ... 
       Roles = ... 

      }); 
     }); 

     return taskCompletionSource.Task; 
    } 

これは素晴らしいです。しかし、私はすべてのOWIN/Katanaチュートリアルで見られる気の利いた[Authorize]属性を使うことを好むでしょう。オーサインミドルウェアが、Authorize属性を使用する以外は、今のようにValidateメソッドに対してjwtトークンを検証する方法はありますか?

EDIT

だから私は、次のミドルウェアを実装し、私の起動クラスでそれを使用します。

public class AuthorizationMiddleware : OwinMiddleware 
{ 
    private OwinMiddleware _next; 

    public AuthorizationMiddleware(OwinMiddleware next):base(next) 
    { 

    } 

    public override async Task Invoke(IOwinContext context) 
    { 
     var jwt = context.Request.Query.Get("jwt"); 

     if (jwt != null) 
     { 
      var userValidationResult = await Utility.ValidateUser(jwt); 

      if (userValidationResult.Validated) 
      { 
       var jwtoken = new JwtSecurityToken(jwt); 

       var identity = new ClaimsIdentity("jwt"); 

       //foreach (var role in userValidationResult.Roles) 
       // identity.AddClaim(new Claim(ClaimTypes.Role, role)); 

       identity.AddClaim(new Claim(ClaimTypes.Email, userValidationResult.Email)); 

       context.Request.User = new ClaimsPrincipal(identity); 
      } 
     } 

     await _next.Invoke(context); 
    } 
} 

public class Startup 
{ 

    public void Configuration(IAppBuilder app) 
    { 
     app.Use<AuthorizationMiddleware>(); 

     var config = new HttpConfiguration(); 

     app.UseWebApi(config); 
    } 
} 

しかし、私はAuthorize属性で飾られたルートのどれもが私のいずれかを打つように見えるんinvokeメソッド内のブレークポイント。そして、私はいつも無許可の401を取り戻します。これはなぜですか?

答えて

2

OWINパイプラインの上に基本ミドルウェアを実装することができます。

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     app.Use(async (ctx, next) => 
     { 
      var jwt = ctx.Request.Query.Get("jwt"); 

      if (jwt != null) 
      { 
       var userValidationResult = await Utility.ValidateUser(jwt); 

       if (userValidationResult.Validated) 
       { 
        var identity = new ClaimsIdentity("jwt"); 

        foreach(var role in userValidationResult.Roles) 
         identity.AddClaim(new Claim(ClaimTypes.Role, role)); 

        identity.AddClaim(new Claim(ClaimTypes.Email, userValidationResult.Email)); 

        //etc... add every claim 

        ctx.Request.User = new ClaimsPrincipal(identity); 
       } 
      } 

      await next.Invoke(); 
     }); 

     var config = new HttpConfiguration(); 

     app.UseWebApi(config); 

     //etc... 
    } 
} 

これは単なるスタブである、あなたはそれがあなたの特定の環境で動作させるためにコードを拡張する必要があるかもしれません:シンプルが要件を満たすことが何か。

このようなミドルウェアはRequest.Userを設定し、他のミドルウェア(Web API Authorizeフィルタが含まれています)で使用されます。 [Authorize()]属性を使用してコントローラ/アクションを自由に飾ることができます。

さらに柔軟なものが必要な場合は、how to implement an authentication middlewareについて詳しく読むことをお勧めします。

このリソースはBrock Allenがこのような実装でも役に立ちます:OWIN Authentication Middleware Architecture

+0

私は依然としてAuthorize属性を制御していないようです。質問編集を参照してください。 – jth41

+0

ミドルウェア自体は 'Authorize'属性とは関係がありません。コントローラは 'Authorize'で装飾されています)。 'Startup.cs'内のメソッドが呼び出されていますか?同じプロジェクトで 'Global.asax'を使っていますか? –

+0

また、Web APIを設定していますか?あなたのコードを見ると、 'Startup.cs'ファイルのどこにでも' WebApiConfig.Register(config) 'を呼び出さないようです。 –

関連する問題