私はサードパーティのプロバイダがOauth2ベースの認証サーバーとして機能するプロジェクトに取り組んでいます。認証サーバーにユーザーを(ログイン/パスワードを使用して)送信し、認証サーバーがMVCクライアントにアクセストークンを返すAsp.net MVC 5ベースのクライアント。アクセス・トークンを使用してリソース・サーバー(API)へのそれ以上の呼び出しが行われます。OWIN OpenID接続許可がセキュリティで保護されたコントローラ/アクションの承認に失敗する
これを達成するために、Microsoft.Owin.Security.OpenIdConnectとUseOpenIdConnectAuthentication拡張を使用しています。認証サーバーからアクセストークンを正常にリダイレクトして取得できましたが、クライアントは認証Cookieを作成していません。保護されたページにアクセスしようとするたびに、アクセストークンを持つコールバックページが表示されます。
私はここで何が欠けていますか?私の現在のコードは以下の通りです。
セキュアコントローラのアクション:
namespace MvcWebApp.Controllers
{
public class SecuredController : Controller
{
// GET: Secured
[Authorize]
public ActionResult Index()
{
return View((User as ClaimsPrincipal).Claims);
}
}
}
起動クラス:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType("ClientCookie");
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AuthenticationType = "ClientCookie",
CookieName = CookieAuthenticationDefaults.CookiePrefix + "ClientCookie",
ExpireTimeSpan = TimeSpan.FromMinutes(5)
});
// ***************************************************************************
// Approach 1 : ResponseType = "id_token token"
// ***************************************************************************
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType,
SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(),
Authority = "https://thirdparty.com.au/oauth2",
ClientId = "_Th4GVMa0JSrJ8RKcZrzbcexk5ca",
ClientSecret = "a3GVJJbLHkrn9nJRj3IGNvk5eGQa",
RedirectUri = "http://mvcwebapp.local/",
ResponseType = "id_token token",
Scope = "openid",
Configuration = new OpenIdConnectConfiguration
{
AuthorizationEndpoint = "https://thirdparty.com.au/oauth2/authorize",
TokenEndpoint = "https://thirdparty.com.au/oauth2/token",
UserInfoEndpoint = "https://thirdparty.com.au/oauth2/userinfo",
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = n =>
{
var token = n.ProtocolMessage.AccessToken;
// persist access token in cookie
if (!string.IsNullOrEmpty(token))
{
n.AuthenticationTicket.Identity.AddClaim(
new Claim("access_token", token));
}
return Task.FromResult(0);
},
AuthenticationFailed = notification =>
{
if (string.Equals(notification.ProtocolMessage.Error, "access_denied", StringComparison.Ordinal))
{
notification.HandleResponse();
notification.Response.Redirect("/");
}
return Task.FromResult<object>(null);
}
}
});
// ***************************************************************************
// Approach 2 : ResponseType = "code"
// ***************************************************************************
//app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
//{
// AuthenticationMode = AuthenticationMode.Active,
// AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType,
// SignInAsAuthenticationType = app.GetDefaultSignInAsAuthenticationType(),
// Authority = "https://thirdparty.com.au/oauth2",
// ClientId = "_Th4GVMa0JSrJ8RKcZrzbcexk5ca",
// ClientSecret = "a3GVJJbLHkrn9nJRj3IGNvk5eGQa",
// RedirectUri = "http://mvcwebapp.local/",
// ResponseType = "code",
// Scope = "openid",
// Configuration = new OpenIdConnectConfiguration
// {
// AuthorizationEndpoint = "https://thirdparty.com.au/oauth2/authorize",
// TokenEndpoint = "https://thirdparty.com.au/oauth2/token",
// UserInfoEndpoint = "https://thirdparty.com.au/oauth2/userinfo",
// },
// Notifications = new OpenIdConnectAuthenticationNotifications
// {
// AuthorizationCodeReceived = async (notification) =>
// {
// using (var client = new HttpClient())
// {
// var configuration = await notification.Options.ConfigurationManager.GetConfigurationAsync(notification.Request.CallCancelled);
// var request = new HttpRequestMessage(HttpMethod.Get, configuration.TokenEndpoint);
// request.Content = new FormUrlEncodedContent(new Dictionary<string, string>
// {
// {OpenIdConnectParameterNames.ClientId, notification.Options.ClientId},
// {OpenIdConnectParameterNames.ClientSecret, notification.Options.ClientSecret},
// {OpenIdConnectParameterNames.Code, notification.ProtocolMessage.Code},
// {OpenIdConnectParameterNames.GrantType, "authorization_code"},
// {OpenIdConnectParameterNames.ResponseType, "token"},
// {OpenIdConnectParameterNames.RedirectUri, notification.Options.RedirectUri}
// });
// var response = await client.SendAsync(request, notification.Request.CallCancelled);
// response.EnsureSuccessStatusCode();
// var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
// // Add the access token to the returned ClaimsIdentity to make it easier to retrieve.
// notification.AuthenticationTicket.Identity.AddClaim(new Claim(
// type: OpenIdConnectParameterNames.AccessToken,
// value: payload.Value<string>(OpenIdConnectParameterNames.AccessToken)));
// }
// }
// }
//});
}
}
私はresponse_type = "id_token token"を試しましたが、使用しているIDサーバ(WSO2 5.0.0)がサポートしているようです。完全なopenid接続機能のために次のバージョンが出るまで待たなければなりません。レスポンスをresponse_type = "code"に変更すると、認証プロセスの最初の部分が完了し、URLにコードが返されますが、アクセストークンを取得する次のリクエストは発生せず、OWINパイプラインでIDが作成されません。 – TejSoft
実際、それはサポートされていないようです:http://stackoverflow.com/a/29140396/542757。残念ながら、OIDCミドルウェアはそれをサポートしていないため、コードフローを使用することはできません(これは残念ですが、ASP.NETチームに何回も言いました)。 ASP.NET 5への移行はオプションですか? – Pinpoint
WSO2がまだ準備されていない場合、ASP.net 5への移行は役に立ちますか? idサーバーは複数のサイトをサポートし、既存のものと新しいもの(ビルド中のもの)をサポートします。新しいものはASP.net 5を使うことができますが、古いものは4.5です。 WSO2がすぐに次のバージョンをリリースするので、私は数週間待つかもしれません。私は2つの方法で質問を更新しました。 – TejSoft