Fork me on GitHub

关于 IdentityServer 部署到生产环境相关问题踩坑记录

Idsr 定义了几种模式适用于不同的场景:

    //
    // 摘要:
    //     OpenID Connect flows.
    public enum Flows
    {
        //
        // 摘要:
        //     authorization code flow
        AuthorizationCode = 0,
        //
        // 摘要:
        //     implicit flow
        Implicit = 1,
        //
        // 摘要:
        //     hybrid flow
        Hybrid = 2,
        //
        // 摘要:
        //     client credentials flow
        ClientCredentials = 3,
        //
        // 摘要:
        //     resource owner password credential flow
        ResourceOwner = 4,
        //
        // 摘要:
        //     custom grant
        Custom = 5,
        //
        // 摘要:
        //     authorization code with proof key flow
        AuthorizationCodeWithProofKey = 6,
        //
        // 摘要:
        //     hybrid flow with proof key
        HybridWithProofKey = 7
    }

 

最近我们把 IdentityServer 部署到了生成环境,为了适用于 cs/bs,app 等不同终端,接入使用了 OAuth2.0 标准规范 AuthorizationCode,ClientCredentials,ResourceOwner,Implicit 的几种模式和 OpenID Connect 协议,整个过程也遇到了各种各样的问题。

启用 HTTPS 后 Endpoint 问题

我们是在 LB 层部署了证书(没有设置在IIS层),IIS 层还是HTTP ,IdentityServer 默认 RequireSsl 强制设置成 false ,当时生成后的 Endpoints 都是 HTTP ,因为默认 IdentityServer 是根据 RequireSsl 的设置来生成URL;最后找到的解决方案是强制设置 PublicOrigin 为 HTTPS 的域名。

Terminating SSL

If you want to terminate SSL on the load balancer, there are two relevant settings on the options:

RequireSsl

Set this to false to allow non-SSL connections between the load balancer and IdentityServer.

PublicOrigin

Since your internal farm nodes have different names than the public reachable address, IdentityServer can’t use it for link generation. Set this property to the public name.

跨域与跳过权限确认页

CORS 是 Cross-Origin Resource Sharing 的缩写,这本质上来自于浏览器的保护机制。当web页面的host与Ajax访问的host不同时,浏览器会使用Http的 OPTIONS 方法,去探测被访问的host是否允许跨域访问。一般就是添加Access-Control-Allow-Origin的头 ,Idsrv 添加如下配置即可 。

                    RequireConsent = true,
                    AllowRememberConsent = true,

                    RedirectUris = new List<string>
                    {
                        "http://localhost:5000/index.html",
                    },

                    AllowedCorsOrigins = new List<string>
                    {
                        "http://localhost:5000"
                    }

 

 第三方资源问题

如果项目中引用了第三方的资源,需要设置

CspOptions = new CspOptions
{
   Enabled = false,
}

 负载环境切换缓存到 redis

//Redis
var redis = ConnectionMultiplexer.Connect(CacheSetting.Redis);
//客户端信息缓存
var clientStoreCache = new ClientStoreCache(redis);
//作用域信息缓存
var scopeStoreCache = new ScopeStoreCache(redis);
//用户信息缓存
var userServiceCache = new UserServiceCache(redis);
//注册客户端缓存-
factory.ConfigureClientStoreCache(new Registration<ICache<Client>>(clientStoreCache));
//注册作用域缓存
factory.ConfigureScopeStoreCache(new Registration<ICache<IEnumerable<Scope>>>(scopeStoreCache));

 定期清理过期的票据(使用EF持久化票据)

var cleanToken = new TokenCleanup(ef, 20);
cleanToken.Start();

 Token handle not found

2017-04-13 14:40:18.9149 ERROR Token handle not found
{
  "ValidateLifetime": true,
  "AccessTokenType": "Reference",
  "TokenHandle": "1d6f4eb15ca3079ac25978be95d7e2f5"
}

偶尔抽风,还没有找到解决方案

https://github.com/IdentityServer/IdentityServer3/issues/2985

https://github.com/IdentityModel/IdentityModel2

负载 XSRF 问题

做负载时需要配置 machineKey

the antiforgery token cookie is protected with the default Owin data protector. If, for some reason, the server does not manage to unprotect the cookie, it'll also treat the scenario as an antiforgery validation failed. In a load balanced environment, unless you take control of configuring the servers to use the same protectors (eg. common machine key), mismatch may happen.

https://github.com/IdentityServer/IdentityServer3/issues/450

https://github.com/IdentityServer/IdentityServer3/issues/1672

IDX10311: RequireNonce is 'true'

IDX10311: RequireNonce is 'true' (default) but validationContext.Nonce is null. A nonce cannot be validated. If you don't need to check the nonce, set OpenIdConnectProtocolValidator.RequireNonce to 'false'.

调试源码,这个错误是由于获取不到 cookie 的的原因,检查 idsrv 的站点 cookie 是否存在,是否使用 IE 并且 iframe 跨域(使用P3P协议自动更改IE浏览器安全级别:http://blog.csdn.net/fdipzone/article/details/43205961)

IDX10316: The 'nonce' has expired

Microsoft.IdentityModel.Protocols.OpenIdConnectProtocolInvalidNonceException
IDX10316: The 'nonce' has expired: '...'. Time from 'nonce': '19/01/2017 13:09:13', Current Time: '19/01/2017 15:48:05'. NonceLifetime is: '01:00:00'

            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                // Set expiration time to 8 hours
                ProtocolValidator = new OpenIdConnectProtocolValidator()
                {
                    NonceLifetime = new TimeSpan(0, 8, 0, 0)
                },
...

,
                    AuthenticationFailed = (context) =>
                    {
                        if (context.Exception is OpenIdConnectProtocolInvalidNonceException && context.Exception.Message.ContainsAny(new string[] { "IDX10316", "IDX10311" }))
                        {
                            logger.Warn("OpenIdConnectProtocolInvalidNonce expired, reauthenticating...");
                            context.HandleResponse();
                            //context.Response.Redirect("/Error.aspx?message=" + context.Exception.Message);
                            context.Response.Redirect(context.Request.Uri.PathAndQuery);
                        }
                        return Task.FromResult(0);
                    },

https://stackoverflow.com/questions/29502788/enabling-ssl-in-asp-net-mvc-5-app-results-in-openidconnectprotocolvalidator-issu

https://teknovenus.com/nonce-expriation-idx10316-workaround-asp-net-mvc/

使用  OpenID Connect  登录成功回调白板

这个问题是上线后发现的,因为本地调试都是OK ,在公司网络访问也是OK(机房在公司,公司环境域名是做了内部 DNS 解析),就是外网不可以,各种日志看,排查了好几天;后面是发现,因为回调会 POST 相关的参数到客户端上,id_token 过长被防火墙截断,因为防火墙缓冲区设置太小的原因,参数如下:

id_token:eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSIsImtpZCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSJ9.eyJpc3MiOiJodHRwczovL3Nzby5jbG91ZGhvdGVscy5jbiIsImF1ZCI6IjEwMDAwMDA1IiwiZXhwIjoxNDk2NTYwMjA1LCJuYmYiOjE0OTY1NjAyMDQsIm5vbmNlIjoiNjM2MzIxNTY5OTYxOTU2NjM4Lk9EZGxaVEJrT1dJdFltVTRNaTAwT1RsaUxUazVaamt0TmpZMFlUa3dOams0TVRFME9EY3pNMk00WldVdE56SXlaaTAwWWpnd0xUbGhaREF0TTJOa05tRTNOelkyTXpKbCIsImlhdCI6MTQ5NjU2MDIwNCwiYXRfaGFzaCI6InJEYVhQcXRaSFZEcUxVSzhscmotUFEiLCJzaWQiOiJhNjBlMDA4NjUyMWU5OWMwOTkxMjJlOWQ1NGU2YTg3MCIsInN1YiI6ImlydmluZyIsImF1dGhfdGltZSI6MTQ5NjU2MDIwNCwiaWRwIjoiaWRzcnYiLCJ1c2VyIjoie1wiVXNlcklEXCI6XCJpcnZpbmdcIixcIlVzZXJOYW1lXCI6XCLlkajmtptcIixcIlVzZXJQd2RcIjpcIioqKioqKlwiLFwiU2FsdFwiOlwiKioqKioqXCIsXCJDaXR5QXJlYUlEXCI6XCIxMDAwMDAwOFwiLFwiQ2l0eUFyZWFOTVwiOlwi5Y2X5Y2O6KW_XCIsXCJDaXR5R3JvdXBJRFwiOlwiXCIsXCJDaXR5R3JvdXBOYW1lXCI6XCJcIixcIkpvYklEXCI6XCJBMDAwM1wiLFwiSm9iVGl0bGVcIjpcIuWfjuWMuumUgOWUruWJr-aAu-ebkVwiLFwiRW1haWxcIjpcInl4ZGVuZ0Bob21laW5ucy5jb21cIixcIkJ1c2luZXNzRGVwXCI6XCJcIixcIlVzZXJTb3VyY2VcIjozLFwiWFR5cGVcIjoyLFwiTW9iaWxlXCI6XCIxMzgxNzk2MzY2MlwiLFwiSG90ZWxDZFwiOlwiMDIxMDY0XCIsXCJIb3RlbE5hbWVcIjpcIuS4iua1t-WcuuS4rei3r-WcsOmTgeermeW6l--8iOWGheWuvu-8iVwiLFwiSG90ZWxKb2JJRFwiOlwiUkpDV0pMXCIsXCJIb3RlbEpvYlRpdGxlXCI6XCLotKLliqHnu4_nkIZcIixcIkJyYW5kQ2RcIjpcIlJKXCIsXCJCcmFuZERlc2NcIjpcIuWmguWutlwiLFwiVXBkYXRlVGltZVwiOlwiMjAxNy0wNS0xOFQwOTo0MDoyMS4wNFwifSIsImFtciI6WyJwYXNzd29yZCJdfQ.c_Dn0xxmLRGsp9_iZ7T2UOhwGf2uVjKwWYeGrKr70HtWDXcoafurb6_JxgEwdcWJzlhv3t9a-Y-LcupLbRBfBO-mP7CcbWM5Jr5zn55-z7RH2QnMlViK17AOOiXrKdCr8kTaGAK2bnkMpYIzk4oUAgWkwS3z0_RQ4G1aAIwIDxRvrKo4DuLwCXGPTYXp7YwAemnpvgywNvDM6yjKEL8KltdKyYWaHg8zxQVEPUOeteLFlsBA6rHJ873YTv-s6XNH3Rx944Sh75qGmPCkv3N3mEIDvHd8emMKyGJ53_Rbr6Jjr6eH_h8XNdwvtSIlH3GRfCgsJXppGxEl-KtRDGaR0w
access_token:eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSIsImtpZCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSJ9.eyJpc3MiOiJodHRwczovL3Nzby5jbG91ZGhvdGVscy5jbiIsImF1ZCI6Imh0dHBzOi8vc3NvLmNsb3VkaG90ZWxzLmNuL3Jlc291cmNlcyIsImV4cCI6MTQ5NjU2MDIwNSwibmJmIjoxNDk2NTYwMjA0LCJjbGllbnRfaWQiOiIxMDAwMDAwNSIsInNjb3BlIjpbIm9wZW5pZCIsInByb2ZpbGUiXSwic3ViIjoiaXJ2aW5nIiwiYXV0aF90aW1lIjoxNDk2NTYwMjA0LCJpZHAiOiJpZHNydiIsImFtciI6WyJwYXNzd29yZCJdfQ.e4DeFyh2Jt6dnsry0ALSbEJpj34lbN0u_iW9YAsc_XlSgWm044LeI19xRzgZvzF4lN_4jjwjvMaQPzOO4MOokSmSAjwnMdVg1j2b9U3c7YyqIUQMueHn1hTr06f2kd2OLYLz38RnNilvFf1xAAF8tXs2TOyrHl9L39i6Nb3I7pQenooIoIbP8yRGpGAztRVBBEHf-b1-7b1wmhaDYEKe_dFOXzlNPRjFzrDhvCcoke2SHJ3Zo60c9JQVUKopFPYUF0EN_TDsS4dHeZCE55tLb--1KJpz7e2WVNGMbts7HGUrlpa4O4mwESxN_c1F3V8YVstdEB7i8xYZCSqQHUdE4Q
token_type:Bearer
expires_in:1
scope:openid profile
state:OpenIdConnect.AuthenticationProperties=Tl--AjNJpswyb_R1ytC6SqEKnWP5FWe969jAIK-tPHj7l5bCYieg5fffC111-Bjur08jIafy5-DNg2ESrenp71it4OBCLnUsLXPbFGxlsT6jWwsTmRgJf5HxG-HtsTZm2iIwDkFl2P4GmlUt7GAl8gMuTNlaLqB3M-RuJ2prt603WzMQ
session_state:UDOKlCOQmRPUjrKy2bRKz-erQ9Ze4jkre7FwspSAZBA.d02260a76d5c74285e125e59531cea07

REFER: https://identityserver.github.io/Documentation/docsv2/advanced/deployment.html

posted @ 2017-03-07 14:26  花儿笑弯了腰  阅读(2545)  评论(2编辑  收藏  举报