約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で機能しました。何が変わったの?
ありがとうございました!
つまり、新しいテンプレートには、以前のテンプレートに存在していたApplicationOAuthProviderの機能的な実装が含まれていないことがわかります。
this build talk を見た後、さらに調査したところ、ApplicationOAuthProviderの実装が this NuGetパッケージ でチェックアウトできることがわかりました。これは、古い実装と非常に似ています。
OAuthAuthorizationServerProviderのValidateClientAuthenticationおよびGrantResourceOwnerCredentialsをオーバーライドする必要があります。
さらに、セキュリティオプションとして個別ユーザーアカウントが選択されている場合は、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
エンドポイントを正しく使用できるようになります。