2015-12-03 9 views
9

私はサードパーティのプロバイダが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))); 
     //   } 
     //  } 
     // } 

     //}); 

    } 
}    

答えて

3

TL; DR:使用ResponseType = "id_token token"、それが動作するはずです。

OpenID Connectでは、response_type=tokenは有効な値ではありません:http://openid.net/specs/openid-connect-core-1_0.html#Authentication。何id_tokenは(も有効code流れを除く)のOpenID接続プロバイダから返されていない場合、例外は常にスローされます。

は時々response_type=tokenがMSFTによって開発されたOIDCミドルウェアでサポートされていない、後方互換性のために実装されています。この他の情報はSO postです。

(備考:SecurityTokenValidatedに、あなたはOIDCミドルウェアはn.AuthenticationTicket = new AuthenticationTicket(...)を使用して作成したチケットを交換している:それは推奨されるアプローチではないですし、基本的な主張を逃すClaimsIdentityになりますあなたは、新しい追加するだけ逢引を削除することを検討し、必要があります。 access_tokenクレームのような申し立て)

+0

私はresponse_type = "id_token token"を試しましたが、使用しているIDサーバ(WSO2 5.0.0)がサポートしているようです。完全なopenid接続機能のために次のバージョンが出るまで待たなければなりません。レスポンスをresponse_type = "code"に変更すると、認証プロセスの最初の部分が完了し、URLにコードが返されますが、アクセストークンを取得する次のリクエストは発生せず、OWINパイプラインでIDが作成されません。 – TejSoft

+0

実際、それはサポートされていないようです:http://stackoverflow.com/a/29140396/542757。残念ながら、OIDCミドルウェアはそれをサポートしていないため、コードフローを使用することはできません(これは残念ですが、ASP.NETチームに何回も言いました)。 ASP.NET 5への移行はオプションですか? – Pinpoint

+0

WSO2がまだ準備されていない場合、ASP.net 5への移行は役に立ちますか? idサーバーは複数のサイトをサポートし、既存のものと新しいもの(ビルド中のもの)をサポートします。新しいものはASP.net 5を使うことができますが、古いものは4.5です。 WSO2がすぐに次のバージョンをリリースするので、私は数週間待つかもしれません。私は2つの方法で質問を更新しました。 – TejSoft

関連する問題