OpenID Connectを実行しようとしています...私のWeb APIのユーザーがOpenID Connectプロバイダーの認証コードを取得できました。このコードをASP.NET Web APIに渡すにはどうすればよいですか?認証コードを使用してアクセストークンを取得できるようにOWINミドルウェアを構成するにはどうすればよいですか?
更新:SPAはAJAX=を使用してWebサービス(ASP.NET Web API)と通信します。WebサービスではOWINミドルウェアを使用します。OpenIDConnectを認証メカニズムとして設定します。Webサービスがは、ユーザーがOpenID Connectプロバイダーのログインページに正常にリダイレクトされたときに初めて呼び出されます。ユーザーはログインし、結果として認証コードを取得できます。このコードは、(私のWebサービスによって)アクセストークン。ただし、このコードをWebサービスに戻す方法(これはヘッダーを使用して行われますか?)と、アクセストークンを取得するために何を構成するかがわかりません。手動でトークンエンドポイントを呼び出すことができると思いますが、代わりにOWINコンポーネントを利用したいと思います。
推奨されるアプローチは、AuthorizationCodeReceived
イベントを使用して、認証コードをアクセストークンと交換することです。 Vittorioには、全体的なフローの概要を示すブログエントリがあります 。
これを設定するStartup.Auth.cs
コードの GitHubのこのサンプルアプリ の例を次に示します。
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = Authority,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
AuthorizationCodeReceived = (context) =>
{
var code = context.Code;
ClientCredential credential = new ClientCredential(clientId, appKey);
string tenantID = context.AuthenticationTicket.Identity.FindFirst("http://schemas.Microsoft.com/identity/claims/tenantid").Value;
string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
AuthenticationContext authContext = new AuthenticationContext(string.Format("https://login.windows.net/{0}", tenantID), new EFADALTokenCache(signedInUserID));
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceID);
return Task.FromResult(0);
},
...
}
注:AuthorizationCodeReceived
イベントは、認証が実際に行われるときに一度だけ呼び出されます。認証コードがすでに生成および保存されている場合、このイベントは呼び出されません。このイベントを強制的に実行するには、ログアウトするかCookieをクリアする必要があります。
BenVはすでに質問に回答しましたが、考慮すべきことは他にもあります。
class partial Startup
{
public void ConfigureAuth(IAppBuilder app)
{
// ...
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
Notifications = new OpenIdConnectAuthenticationNotifications() {
AuthorizationCodeReceived = (context) => {
string authorizationCode = context.Code;
// (tricky) the authorizationCode is available here to use, but...
return Task.FromResult(0);
}
}
}
}
}
2つの問題:
authorizationCode
はすぐに期限切れになります。保管しても意味がありません。AuthorizationCodeReceived
イベントが発生しないことです。何をする必要があるかはAcquireTokenByAuthorizationCodeAsync
を呼び出すことで、それをキャッシュし、TokenCache.DefaultShare
内で適切に処理します。
AuthorizationCodeReceived = (context) => {
string authorizationCode = context.Code;
AuthenticationResult tokenResult = await context.AcquireTokenByAuthorizationCodeAsync(authorizationCode, new Uri(redirectUri), credential);
return Task.FromResult(0);
}
次に、リソースへのevery呼び出しの前に、AcquireTokenSilentAsync
を呼び出してaccessTokenを取得します(これはTokenCacheを使用するか、サイレントにrefreshTokenを使用します)。トークンの有効期限が切れている場合、AdalSilentTokenAcquisitionException
例外が発生します(アクセスコード更新プロシージャを呼び出します)。
// currentUser for ClaimsPrincipal.Current.FindFirst("http://schemas.Microsoft.com/identity/claims/objectidentifier")
AuthenticationResult authResult = await context.AcquireTokenSilentAsync(resourceUri, credential, currentUser);
トークンがキャッシュされている場合、AcquireTokenSilentAsync
の呼び出しは非常に高速です。
カスタム認証を行うには、デフォルトのowin検証をバイパスする必要があります。
new OpenIdConnectAuthenticationOptions
{
...,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = false
},