2015-01-12 9 views
16

私はC#のOAuthでWeb APIを保護するチュートリアルに従ってきました。APIエンドポイントから「このリクエストで承認が拒否されました」が返されます。ベアラトークンを送信するとき

私はいくつかのテストを行っていますが、これまでは/tokenからアクセストークンを正常に取得できました。私はそれをテストするために "拡張RESTクライアント"と呼ばれるChromeの拡張機能を使用しています。

{"access_token":"...","token_type":"bearer","expires_in":86399} 

これは私が/tokenから返すものです。すべてがよさそうだ。

私の次の要求は、私のテストAPIコントローラーにある:

namespace API.Controllers 
{ 
    [Authorize] 
    [RoutePrefix("api/Social")] 
    public class SocialController : ApiController 
    { 
     .... 


     [HttpPost] 
     public IHttpActionResult Schedule(SocialPost post) 
     { 
      var test = HttpContext.Current.GetOwinContext().Authentication.User; 

      .... 
      return Ok(); 
     } 
    } 
} 

要求がPOSTで、ヘッダがあります。

Authorization: Bearer XXXXXXXTOKEHEREXXXXXXX 

私が手を:JSONで返さAuthorization has been denied for this request.

私はGETもやってみましたが、私はそれを実装していないので、メソッドがサポートされていないことを期待しています。

public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider 
{ 
    public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 
    { 
     context.Validated(); 
    } 

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
    { 

     context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); 

     using (var repo = new AuthRepository()) 
     { 
      IdentityUser user = await repo.FindUser(context.UserName, context.Password); 

      if (user == null) 
      { 
       context.SetError("invalid_grant", "The user name or password is incorrect."); 
       return; 
      } 
     } 

     var identity = new ClaimsIdentity(context.Options.AuthenticationType); 
     identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName)); 
     identity.AddClaim(new Claim(ClaimTypes.Role, "User")); 

     context.Validated(identity); 

    } 
} 

すべてのヘルプは素晴らしいことだ:

は、ここに私の認可プロバイダです。私はそれが要求か間違っているコードかどうか分かりません。

編集:ここに は私Startup.cs

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     var config = new HttpConfiguration(); 
     WebApiConfig.Register(config); 
     app.UseWebApi(config); 
     ConfigureOAuth(app); 
    } 

    public void ConfigureOAuth(IAppBuilder app) 
    { 
     var oAuthServerOptions = new OAuthAuthorizationServerOptions() 
     { 
      AllowInsecureHttp = true, 
      TokenEndpointPath = new PathString("/token"), 
      AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), 
      Provider = new SimpleAuthorizationServerProvider() 
     }; 

     // Token Generation 
     app.UseOAuthAuthorizationServer(oAuthServerOptions); 
     app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); 

    } 
} 

答えて

27

問題は非常に簡単です。

public void Configuration(IAppBuilder app) 
{ 
    ConfigureOAuth(app); 
    var config = new HttpConfiguration(); 
    WebApiConfig.Register(config); 
    app.UseWebApi(config); 
} 

構成のOWINパイプラインの順序については、非常に重要です。あなたの場合、OAuthハンドラの前にWeb APIハンドラを使用しようとします。その中で、要求を検証し、アクションを確保し、現在のOwin.Context.Userに対してそれを検証しようとしました。この時点で、このユーザは、後で呼び出されるOAuthハンドラを持つトークンからのセットのために存在しません。

+0

WebApiをパイプラインに登録していない場合はどうすればよいですか?私はデフォルトのWeb APIテンプレートを使って作業しています。 GET要求はうまく動作し、POST要求は私に401を与えます。トークンは同じですが。 – mwijnands

+1

これは私を捕まえた!この回答を投稿する時間をとってくれてありがとう。 – heymega

+0

リファクタリングしてから数時間で無駄になってしまいました。 – Tomino

2

であるあなたは、このスキーマで主張を追加する必要があります行うには

http://schemas.microsoft.com/ws/2008/06/identity/claims/role 

最高のものは、特許請求の範囲の事前定義されたセットを使用することです:あなたはでClaimTypesを見つけることができます

identity.AddClaim(new Claim(ClaimTypes.Role, "User")); 

10。あなたが考慮しなければならない

もう一つは、あなたのコントローラ/アクションのフィルタの役割です:

[Authorize(Roles="User")] 

あなたは自己ホストjqueryのクライアントhereとowin、簡単なサンプルアプリケーションを見つけることができます。

+0

「identity.AddClaim(新しいクレーム(ClaimTypes.Role、 "User"));」を追加しました。ユーザーは資本であることが重要ですか?私はあなたのコメントを見る前にこれを追加しました。私はそれが重要だとは思わないでしょう。私はあなたのリンクをチェックアウトします。 –

+0

これは定数であり、何でもかまいません。 – LeftyX

+0

私は '[Authorize]'を自分のコントローラーに含めるように変更しようとしましたが、私はまだそれを許可するようにはなっていません。私はロール "ユーザー"で新鮮なユーザーを作成し、正常に新しいトークンを得ました。上記の私のコードをあなたの提案された変更で更新しました。 –

0

他のOwinアセンブリと共存する "System.IdentityModel.Tokens.Jwt"のように見えます。

"Microsoft.Owin.Security.Jwt"バージョン2.1.0を使用している場合は、バージョン3.0.2の "System.IdentityModel.Tokens.Jwt"アセンブリを使用する必要があります。

パッケージマネージャコンソールから

、試してください:あなたのOWINパイプラインの 変更順:

Update-Package System.IdentityModel.Tokens.Jwt -Version 3.0.2 
関連する問題