具有mvc和api的身份服务器3客户端未刷新访问令牌

时间:2017-02-28 17:01:08

标签: asp.net-mvc identityserver3 thinktecture-ident-server

我有一个有效的身份提供者。我设计用于对其进行身份验证的客户端是一个结合了MVC和Web API的单个项目。初始身份验证是通过MVC完成的。如果访问令牌无效,则按预期刷新。

MVC方面:

public partial class Startup {

    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 Server 3一起使用。

我很感激任何指导。请。

1 个答案:

答案 0 :(得分: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);

我也设定了发布日期,但这不是强制性的