web-dev-qa-db-ja.com

ASP Identity 2を使用して/ TokenエンドポイントにPOSTすると、常に「invalid_client」エラーを受け取ります

約1か月前、ASP Identity OAuthで完全に機能するプロジェクトがありました。grant_type、username、/ TokenエンドポイントにPOSTリクエストを送信します。とパスワード、そしてすべてがダンディでした。

私は最近、Visual Studio 2013 RC2のSPAテンプレートに基づいて新しいプロジェクトを開始しました。古いテンプレートとは少し異なります。認証はかなり基本的なデフォルトに設定されていますが、

OAuthOptions = new OAuthAuthorizationServerOptions
{
    TokenEndpointPath = new PathString("/Token"),
    //AuthorizeEndpointPath = new PathString("/Account/Authorize"), 
    Provider = new ApplicationOAuthProvider(PublicClientId),
    AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
    AllowInsecureHttp = true
};

デフォルトのテンプレートから大きな変更はありません。実装したWeb APIコントローラーメソッドを使用して、アカウントを正常に登録できます。

    // POST: /Account/Register
    [HttpPost]
    [AllowAnonymous]
    public async Task<IHttpActionResult> Register(RegisterBindingModel model)
    {
        if (ModelState.IsValid)
        {
            var user = new TunrUser() { UserName = model.Email, Email = model.Email, DisplayName = model.DisplayName };
            var result = await UserManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {
                return Created(new Uri("/api/Users/" + user.Id,UriKind.Relative), user.toViewModel());
            }
            else
            {
                return BadRequest(result.Errors.First());
            }
        }
        return BadRequest(ModelState);
    }

ただし、私が/ Tokenエンドポイントに対してPOST=であっても)alwaysは同じ応答を取得します。

{"error":"invalid_client"}

通常、私は次のリクエストボディを渡します

grant_type=password&username=user%40domain.com&password=userpassword

しかし、これは同じエラーになります。これは、以前のVS2013 SPAテンプレート/ Identityで機能しました。何が変わったの?

ありがとうございました!

19
Hayden McAfee

つまり、新しいテンプレートには、以前のテンプレートに存在していたApplicationOAuthProviderの機能的な実装が含まれていないことがわかります。

this build talk を見た後、さらに調査したところ、ApplicationOAuthProviderの実装が this NuGetパッケージ でチェックアウトできることがわかりました。これは、古い実装と非常に似ています。

3
Hayden McAfee

OAuthAuthorizationServerProviderのValidateClientAuthenticationおよびGrantResourceOwnerCredentialsをオーバーライドする必要があります。

ここの例を参照してください: http://www.tugberkugurlu.com/archive/simple-oauth-server-implementing-a-simple-oauth-server-with-katana-oauth-authorization-server-components-part- 1

さらに、セキュリティオプションとして個別ユーザーアカウントが選択されている場合は、WebApiテンプレートに付属のApplicationOAuthProviderクラスを使用できます。ただし、他にいくつか変更する必要があります。これについては、以下に記載します。お役に立てば幸いです。

WebApi/Individual User Accountsテンプレートに付属するApplicationOAuthProviderクラスには、次のメソッドが含まれています。

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();

        ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);

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

        ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
           OAuthDefaults.AuthenticationType);
        ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
            CookieAuthenticationDefaults.AuthenticationType);

        AuthenticationProperties properties = CreateProperties(user.UserName);
        AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
        context.Validated(ticket);
        context.Request.Context.Authentication.SignIn(cookiesIdentity);
    }

これをSPAテンプレートプロジェクトのApplicationOAuthProviderクラスにコピーし、元のメソッドを上書きします。 ApplicationUserクラスは「ベアラー」認証タイプを許可しないため、SPAテンプレートプロジェクトにコピーした場合、コードuser.GenerateUserIdentityAsyncメソッドは無効です。

次のようなオーバーロードをApplicationUserクラスに追加します(Models\IdentityModels.csファイルで見つけます)。

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager , string authenticationType)
    {
        var userIdentity = await manager.CreateIdentityAsync(this , authenticationType);
        // Add custom user claims here
        return userIdentity;
    }

これで、/Tokenエンドポイントを正しく使用できるようになります。

1
Michael Daw