2017-02-28 111 views
1

我有一個工作身份提供商。我設計的客戶端是一個結合了MVC和Web API的單個項目。最初的身份驗證是通過MVC完成的。如果訪問令牌變得無效,則按預期進行刷新。身份服務器3客戶端與mvc和api不刷新訪問令牌

MVC側:

公共部分類啓動{

public void ConfigureAuth(IAppBuilder app) 
    { 
     //AntiForgeryConfig.UniqueClaimTypeIdentifier = "sub"; 
     JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); 

     app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationType = "Cookies", 
      CookieName = "CookieName", 
      ReturnUrlParameter = "/Dashboard", 
      LogoutPath = new PathString("/"), 
     }); 
app.UseOpenIdConnectAuthentication(GetOpenIdConnectAuthenticationOptions()); 

    } 


    private OpenIdConnectAuthenticationOptions GetOpenIdConnectAuthenticationOptions() 
    { 
     var options = new OpenIdConnectAuthenticationOptions 
     { 
      ClientId = "client.id", 
      Authority = AuthorityUrl, 
      RedirectUri = RedirectUri, 
      PostLogoutRedirectUri = RedirectUri, 
      ResponseType = "code id_token", 
      Scope = "openid profile email offline_access roles company utc_offset service_api", 

      TokenValidationParameters = new TokenValidationParameters 
      { 
       NameClaimType = "name", 
       RoleClaimType = "role" 
      }, 

      SignInAsAuthenticationType = "Cookies", 
      Notifications = GetOpenIdConnectAuthenticationNotifications() 
     }; 
     return options; 
    } 

    private OpenIdConnectAuthenticationNotifications GetOpenIdConnectAuthenticationNotifications() 
    { 
     var container = UnityLazyInit.Container; 
     var authorizationProvider = container.Resolve<AuthorizationProvider>(); 
     var notifications = new OpenIdConnectAuthenticationNotifications 
     { 
      AuthorizationCodeReceived = async n => 
      { 
       authorizationProvider.Authority = Authority; 
       authorizationProvider.LoginMethod = LoginMethod; 
       var tokenResponse = await authorizationProvider.GetAccessAndRefreshTokens(n); 

       var userInfoClaims = await authorizationProvider.GetUserInfoClaims(tokenResponse); 

       userInfoClaims = authorizationProvider.TransformUserInfoClaims(userInfoClaims); 

       // create new identity 
       var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType); 
       id.AddClaims(userInfoClaims); 

       id.AddClaim(new Claim("access_token", tokenResponse.AccessToken)); 
       id.AddClaim(new Claim("expires_at", DateTime.Now.AddSeconds(tokenResponse.ExpiresIn).ToLocalTime().ToString())); 
       id.AddClaim(new Claim("refresh_token", tokenResponse.RefreshToken)); 
       id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); 
       id.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity.FindFirst("sid").Value)); 

       var user = authorizationProvider.GetUser(id); 

       var applicationClaims = authorizationProvider.GetApplicationClaims(user); 
       id.AddClaims(applicationClaims); 

       var permisionClaims = authorizationProvider.GetPermisionClaims(user); 
       id.AddClaims(permisionClaims); 

       n.AuthenticationTicket = new AuthenticationTicket(
        new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType, "name", "role"), 
        n.AuthenticationTicket.Properties); 
      }, 

      RedirectToIdentityProvider = n => 
      { 
       // if signing out, add the id_token_hint 
       if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) 
       { 
        var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token"); 

        if (idTokenHint != null) 
        { 
         n.ProtocolMessage.IdTokenHint = idTokenHint.Value; 
        } 
       } 

       return Task.FromResult(0); 
      } 

     }; 

     return notifications; 
    } 

} 

表示層(瀏覽器端)利用angulerjs但是我沒有併入用於認證的任何支持。我依靠MVC。

當表示層調用API時,它會自動根據MVC檢索的訪問令牌進行驗證,但如果過期則無法刷新訪問令牌。它也不會返回未經授權的。它似乎試圖刷新,但失敗。當api調用嘗試刷新令牌時,演示文稿將接收身份提供者的錯誤頁面的HTML。

我該如何解決這個問題?在我看來,它應該在MVC和API合併時自動進行身份驗證和刷新,但這不適用於我。

注意澄清上面的啓動配置是共享的,但MVC和API。

  new Client 
      { 
       ClientName = "MVC Client", 
       ClientId = "client.id", 
       ClientSecrets = new List<Secret> { 
        new Secret("secret".Sha256()) 
       }, 
       Flow = Flows.Hybrid, 

       AllowedScopes = new List<string> 

       { 

        Constants.StandardScopes.OpenId, 

        Constants.StandardScopes.Profile, 

        Constants.StandardScopes.Email, 

        Constants.StandardScopes.OfflineAccess, 

        "roles", 

        "company", 

        "utc_offset", 

        "service_api 

「 },

   RequireConsent = false, 


       RedirectUris = new List<string> 

       { 

        REMOVED 
       }, 


       PostLogoutRedirectUris = new List<string> 
       { 
        REMOVED 
       }, 


       AllowedCorsOrigins = new List<string> 
       { 
        REMOVED 
       }, 

       AccessTokenLifetime = 60, 
       IdentityTokenLifetime = 60, 
       AbsoluteRefreshTokenLifetime = 60 * 60 * 24, 
       SlidingRefreshTokenLifetime = 60 * 15, 
      }, 

@brockallen - 。短的,這是我有一個應用程序,MVC和的WebAPI和Anjulgarjs我不認爲這樣的混合動力是明智的,但我繼承了這個應用程序,現在我已經找到一種方法,使其與Idnetity服務器工作3

我將是任何指導表示感謝。請。

回答

1

我和你有同樣的問題。問題是你正在爲MVC設置一個cookie,但是你沒有設置到期日期,因此MVC不知道cookie已經過期。你需要做的是設置了AuthenticationTicket到期日按以下方式:

    n.AuthenticationTicket.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)); 
        n.AuthenticationTicket.Properties.IssuedUtc = DateTime.Now; 
        //Add encrypted MVC auth cookie 
        n.AuthenticationTicket = new AuthenticationTicket(
         nid, 
         n.AuthenticationTicket.Properties); 

我還設置了發行日期,但這不是強制性

相關問題