在搭建 IdentityServer 服务端后,我们尝试使用了 OIDC(OpenID Connect) 的中间件来代替了原先的 Session 系统认证方式,起初采用的是 HTTP 协议,一切都没有什么问题,最近启用全站 HTTPS 后,发现登陆会跳转到 HTTP的页面,

OpenID Connect 认证流程

第一步:

请求构造授权页

  1. Request URL:https://sso.xxx.cn/connect/authorize?client_id=10000005&redirect_uri=https%3A%2F%2Fp2.cloudhotels.cn&response_mode=form_post&response_type=id_token%20token&scope=openid%20profile&state=OpenIdConnect.AuthenticationProperties%3DTl--AjNJpswyb_R1ytC6SqEKnWP5FWe969jAIK-tPHj7l5bCYieg5fffC111-Bjur08jIafy5-DNg2ESrenp71it4OBCLnUsLXPbFGxlsT6jWwsTmRgJf5HxG-HtsTZm2iIwDkFl2P4GmlUt7GAl8gMuTNlaLqB3M-RuJ2prt603WzMQ&nonce=636321569961956638.ODdlZTBkOWItYmU4Mi00OTliLTk5ZjktNjY0YTkwNjk4MTE0ODczM2M4ZWUtNzIyZi00YjgwLTlhZDAtM2NkNmE3NzY2MzJl&x-client-SKU=ID_NET&x-client-ver=1.0.40306.1554
  2. Request Method:GET
  3. Status Code:200
  4. Remote Address:222.186.49.226:443
  5. Referrer Policy:no-referrer-when-downgrade
  1. :authority:sso.xxx.cn
  2. :method:GET
  3. :path:/connect/authorize?client_id=10000005&redirect_uri=https%3A%2F%2Fp2.xxx.cn&response_mode=form_post&response_type=id_token%20token&scope=openid%20profile&state=OpenIdConnect.AuthenticationProperties%3DTl--AjNJpswyb_R1ytC6SqEKnWP5FWe969jAIK-tPHj7l5bCYieg5fffC111-Bjur08jIafy5-DNg2ESrenp71it4OBCLnUsLXPbFGxlsT6jWwsTmRgJf5HxG-HtsTZm2iIwDkFl2P4GmlUt7GAl8gMuTNlaLqB3M-RuJ2prt603WzMQ&nonce=636321569961956638.ODdlZTBkOWItYmU4Mi00OTliLTk5ZjktNjY0YTkwNjk4MTE0ODczM2M4ZWUtNzIyZi00YjgwLTlhZDAtM2NkNmE3NzY2MzJl&x-client-SKU=ID_NET&x-client-ver=1.0.40306.1554
  4. :scheme:https
  5. accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  6. accept-encoding:gzip, deflate, sdch, br
  7. accept-language:zh-CN,zh;q=0.8
  8. cookie:acw_tc=AQAAACVlAyxojQIAFpTodHdoRw2DIBLj; idsrv.xsrf=lL0mbSQCJwUEqyWAufNmPsKzR6s4rlmo9TnH5RgESnOUtVXBzRBfF1bumRiySNSdyI8LDA; SignInMessage.410d3116e4685a1ff945b72ec5b7bdee=owpop5ySCBwDREEoMovtaEIsnr5k6JVvD8kbdp2dJlSJvAUWX6xXvR1qP_G-C-Hf6QOOV8M5wZ_HBJ8L-101uznPFSmw1lqkmnPHTj0xJeR3gJ4QeaP9IEm4sQvEyZWzdnNGwW-F_y_9ooSGDqpNEr-PFoI_nrK7az0PWvgHsqv-hKSBQVonq_AIPaGumS7p5ORNHkHwB1LdJXWXnVwFq6NMM1DLD1zXJgpXp4EkzjCExIA89Nd9wUYZlJDb1TuNGLpucraql9RZ6kpKJpnr4z2bGtW1JENWdPb3YH4thqBlP6JMz4s9rKCJWhrOtojpuqfzGUanE-Sw8he4My0GQQ3FcNPqT8GFaVUmwPpy8qIZriLyCRO6IUlXoqo_uwAHS2N5f3AYtaoIo88TEJZl8sZCIeM1QD2ZADB1L96JHuTzMAR7TLEWxtFrFmlIX4Ue0XyXclzQnKbNPnhFlwK11joxFxpVczMuUp4bpEvfdhmuFaqTkTqO9qOmxh3fiVQxqpv9LXNg-JFrAWzlXfSJmrFaRUJ6-RFbHi31cYkLQ0v4Gal7KASMsVTvp9Iswj1lgvRtHoMEAXmwyMWThZg6RGJbFrQQSjG2uFB7-LFCOI_V_d3EYQMHxkvFeFJHUQ4O9DbXq0v-nSXCzcyNYEXBUS273X6OensJ4nilWZVtnssyXh1SppSICXGnX1MHfNvWMp2AlmdQQo76myLL0l2yCRVpyP6fLGWcMUmn9MmQi5-NoIALlCNyOslwAOGsgCkpcpLEeeI0BD7SKwXzQZQnTgCtJJayMZVdPB3aEKojZFe1BsBUV8nwsdEAhY8dc6HZPY3wpGhrVK1tYH1KzCFt1yw2LI3qgKgQyGnqETk7GUD-gunrvMYym-CMjteLu7lSyOiaaRTjMWb8o35psxK8RvHRNqc; _pms_session=gyyabpm4wizgtp0drl02nuuf; SignInMessage.9d3ece88ead86da0d24435c1a430c34e=NGNDv77kQPUAKKXDc9uVuokKTz1CIJG0t1G81CCrtHgPxx2wEb1TwxRdCT7UV61lmQxF-kYGSXH2-irds7PfoQSdp4Wm4Aot-zOjtpjtR8aH5VEndu78hbGIv6n2JEOAUQBtfh2GTrmQYBgHpEHIulCrHJWovGVmFIsgjDHmpnzAz_Kf6ZmcL0sC2tFDZYKP2PTYkaF83cG3PYbqVIeM7HTuucORtaybnuzv15UxGKU4T28cZwI28d_u-Og8gXkAoYNNFnT054S-q_Coxhz1nR5rYAZe_WmLZCvqM_3D0M7IK_1nHN8NexBKyuRIZ9V25D4afl7rNROCb2A0m3Y3ayUgu3FySHZwcjjhsia_l16IJMVu6KjFJCVZHh6JGu06O6lTza8QUnvYA6vh-PWVFiLFoszUy16RxuDWJl_fnoaWFBxP97zhFZ7gCHj9zdr5BjEgko6fkoEIcmHosehqsrTYJUGPKkaKR2GUfKzCEBeoNFvUveCOXrrjayeCSw5hk6dEjdehQvjrBy7ezffBRgViimpBr0YLqH00WSRdsZzfBA_KlUBkE3zJDBIrmGkyB7xiTOSHFXT-CoC4g7rEF4usM44CCntWTO48UGd_eq6qIxSLjVhXGrsuauqXZTKs82mPmARsd85opyA69kHfDkHT2vCKT3GLVmvBxk4Sdi1zoCobyHohFpj0o-u0J9fko6W8uxhilcKovPeWh8yDp5CQrpquXKc6yAN-4x1Lyh-lnKKHm2m1uPSV0v04P4PZfBYqASkYtgSKTRcmwErF8l8H7XpqlWFRT2DdXWYwetTv2I5MhC6HqwIlVoYzBk3JRIGheYTazNaO8Mz3pm1Ayp0VIWPH36mvdXynMV5iJmqgccVkWpdHmwJbHzdYajWPtqYocartaA2pAU9zog4nneNs9KI; SignInMessage.2e3550a6f27dbe37def555603163623e=dQUu6i3OyRhbsoYaK7wbtzSK5xGjVNSmenWCdZ0wbSvAnMAK7KNmBLBCOcV9rKRxAA-9jehtXT7bkFA0NRptXfgrWrU_my-cVvC2ok72b7qwk4LGTHonPqklVl-L_xCCBkUe0svpP1C4B3etBAj5MotsOVNFHuyhkNDAfMt_HpA6fCUJnEZtfQ0i3qycFmwL67O4JQx1EEbvhuugnlbyDiahppUlc-_TeVoySc_SNpnJc8HC9fCkYm7p2vQaLZoWVUsROU-JCPeIJ8NRDISTMqYlSWL0QY1UNa8vXF7zLSGO8jfMQ5YdmpYJIwG7VZrqf4yqHKi9E14G0IhYi1Y99wddOyaPYIKIQGIhWHkWVkRX0E1Mq-gsvzXJzLlN0-0_Ywyt4VRtpE1tQz9iS4xAtNPZBp3xyBzPJ0KsM6sHOuxuZT3X0NQV7hIZRA1eIV4xKhrGJtlh59FC7BaCmVIDDV7dytO9AGMlO5iYSjgKI4bTGC8cGYXHs2k7BsFTEh_RWKg0ygyu3hjvjIgN4X67yQ4BGHv92iFwLUxEn4nBXb7oZEx7BawzYAFcTlCK-l81VPmwr2Is0FjnhYlcr7MS-tvUx3HmG758-QPpoth5T0oZrOKVwv8Pop1503VjS1hFF1MCEzp0zzXaJcjZ_XeDLWmzElZ9jl8pw4AB2I64W-33IWtxBBXgjc9iX1L4t8imT9EMKXKK6wDxTZNQ8uxL2rnoV6NmYRoVcFjR0CFnAhntZDvhNGPWcFtH-eaGeFgDxa8HlbBV4vk1yNDlxN4-4upJxO7fbWmXx3OGPo8IVydyeQI0pUF61UKXYzVekyjc2rMS7wEpVsd8LdOy147tXLeZwqHBVbgU8GA6uITahJdjatOB2RLgTKgJvb_IPfgQQhRNv4ur5q2cfqerTIzSmH1lOJI; SignInMessage.249b0aeaa528d65e2fabdac9f695167d=PoHjxvv3eyxmJKkLNVuho_DAgPaIEjTg0XfzznyM_sKpPQ5vATFKZRIO7h2b9Zf-OtjqdTQN4gvEewnlEOVOvNED-WVT_hTcmBrj22ghMEKXJhYzjjVNOJxc5nYjcI0BHCiNgFsBZyTqsVqGG-QINfID8iG2NpnROU3sLygzIObydw56IJj63N6kJTBemCompDHcm0V8yOuqr8DIu_jR02JCPYotz2nRuHTsN-SRLCJzm1Q5ggfiy5HMMdV0jkdMj2CirxQV3sri32VNVNCvZ0XZJxFd5Ut-xoVfyPU9gGx1FI7iIEDhXyjSNGHgTGo2DFmgTVRn7kVIHnJ5kRiMvM9fYl8PHz2e_pB8VEGuUCisrXrQjdCiaTHdxjFudlmS-IcRksQV9fx4K0Ug0uy9Luf9RrfnUQo8i8JyARtPdrjmguJ79LVOjL-8eblBQlgUB6ih6uwXLBvRziyDTaB4B2FBT--Ke4guwrYBvxJdIgMh7Up5eJne8UW6Qeoc30L6q3TqiFLQLiFS39lehwx7EqoG_xLnp2y133ClQqfbFSBlBnPZD0OvNSuiWnOE724NeqioVkACPWUFgF7X1fbPDQXLc9mfRt0aNwlipNnCKtKwAoXtFJby1skdLx_I18uALo3KAwptivFweCvtKLELv0dBcQxzRzzOcIPi_gNUdrXnS7z23DvhCbsu8q842J-wZeqwXMrwakUzhh1-FvQW4Agt7FrTOCmOS1KzmarC2Xm5srIH3hWGc3gsvT3NYZxM0k-5WAhHw_d16zLAIWW4K_euxz5GnX-qKwvT3Rcpui4DsKQvZQGfCg4Ua3KKQT1iN-YOuixKMQ7nSiIHaP_0qZYI5H16mj3eiW4w0D2mDUSWCCRmJ7BR5qak0_mH0uLodDVvd8oejbfivWt-SGAd0MnZsoU; SignInMessage.8773da773d34dd5079a297ef19316ac0=4KfGGFxV7E7AiKGysQXQS9Dszsj3xHqg2RaVgdc-0uSz8c6ZLf_4ZB2FA1HLFXxoTnFbU-EN86eB1ZjPdYZO1BRPWw4dt_pk-ojgj88HcdDFlshoQBwAoN6MeTlnEriewC78lYz7UZVDJnCFZki4J7dMGPwu7XM93sLif3cR-d0pIFPdLBsjBZ2XaEDi6B9kKN8IAt5afWT8St-1LgnHSJPWl6iiCj2T71NaNnE0XU1ij_JdQRzLIQy4Z0eG8HA-jH3J_0oaqqoR-X3aJAiNlvb_GMPvXWF6CXaWFPiSxpu8_ApjKeI3Sq5bPghCZdApTdV1BH5UWDPciyZmX1knQd3B8DkmSsrAdSYXq5XVSDB4VYRFbZti-Msd5vZlCTo6w9tcGdNRlAnv9aEZjopkkf8IQqgiW0xZFlQjS9oGEVyNv80BkuhMMmoeNaEotHOaoK3qkNswqJRUNWxT9-6lLKB8pUaDxZZE4dJVC2VnW-CK6nbdDqCACcA-Ayf2wCTy2iVknv_zUUyXW5AkUO0CPI1BrBJkc_GqCbymXJphKO44vNLVUBoaMNjdAkqktpHBYx_rXImhCHNdXh0hvsVST4EWlTb2Y6IHx4G4sWNqE7irBPqhFJ4GcSUCfZlM0MD_72JdNCo9sYRDXqBUKO4gx1yRg2pyO00R0ch604AJ5EsF2fotrUm7Ie3br2erdI3dKkuKmy2jpyPQG3NmsZVFXFqIzguX7v4YvQTXXbvlVNHRpj3ulgGL7EQwnaikOD1Zc6mntSyesZ19nrkIQqjeFNFYA22-myhhFDo9ukjm0JIqvLoBLCN5br0JnyTXfHj0Bai_OsR1JMqoBSC9ZYHcSpEkNGDgi_gGiN1rQWUQikxhV3I5T1thx0A4_otw3MV2BMOWKxNMBdI4-jO4AAoWPK4BtFI; idsvr.session=a60e0086521e99c099122e9d54e6a870; idsrv=FXCKHsF7lWgZ6xBWmn5VU8KmB3Uo_DPkYFTsRNvEH3CKFOW4is94zus3LN9lPVj6yOqoV2o36dl5FS3tBTOWphg1fzIShAbW522-_AKnL0I3kKQldeccu7Wusb1moa2iAjq9q3y7mxlGFGBP7itBigCY1cfHeAZGbBfx1R1O5RUBO2Zjwf0PZuH1_-0EexZUNn-8qwOaMrpVTVTUOjZqc1Lr0cFFc6_PyLsyhHWbuiZLRcIHSsf_tSiw1YorIWFgoEv8kRlHOc4squfvAQQsraxBRrIKqWieqqhCA1y7kGUvlBJV8I0eLmP6lu9S08kehlM4sw
  9. referer:https://sso.xxx.cn/login?signin=249b0aeaa528d65e2fabdac9f695167d
  10. upgrade-insecure-requests:1
  11. user-agent:Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Mobile Safari/537.36

第二步:

请求构造授权页会返回一个OAuth2回传信息 POST 到客户端 ,OAuth 2.0 Form Post Response Mode ,是一个对 OAuth2 的扩展,构造回传信息提交到客户端是通过URL的querystring和fragment这两种方式,这个扩展标准提供了一基于form表单的形式把数据post给客户端的机制。

  1. Request URL:https://p2.xxx.cn/
  2. Request Method:POST
  3. Status Code:302
  4. Remote Address:58.220.27.80:443
  5. Referrer Policy:no-referrer-when-downgrade
  6.  
  7. 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
  8. access_token:eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSIsImtpZCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSJ9.eyJpc3MiOiJodHRwczovL3Nzby5jbG91ZGhvdGVscy5jbiIsImF1ZCI6Imh0dHBzOi8vc3NvLmNsb3VkaG90ZWxzLmNuL3Jlc291cmNlcyIsImV4cCI6MTQ5NjU2MDIwNSwibmJmIjoxNDk2NTYwMjA0LCJjbGllbnRfaWQiOiIxMDAwMDAwNSIsInNjb3BlIjpbIm9wZW5pZCIsInByb2ZpbGUiXSwic3ViIjoiaXJ2aW5nIiwiYXV0aF90aW1lIjoxNDk2NTYwMjA0LCJpZHAiOiJpZHNydiIsImFtciI6WyJwYXNzd29yZCJdfQ.e4DeFyh2Jt6dnsry0ALSbEJpj34lbN0u_iW9YAsc_XlSgWm044LeI19xRzgZvzF4lN_4jjwjvMaQPzOO4MOokSmSAjwnMdVg1j2b9U3c7YyqIUQMueHn1hTr06f2kd2OLYLz38RnNilvFf1xAAF8tXs2TOyrHl9L39i6Nb3I7pQenooIoIbP8yRGpGAztRVBBEHf-b1-7b1wmhaDYEKe_dFOXzlNPRjFzrDhvCcoke2SHJ3Zo60c9JQVUKopFPYUF0EN_TDsS4dHeZCE55tLb--1KJpz7e2WVNGMbts7HGUrlpa4O4mwESxN_c1F3V8YVstdEB7i8xYZCSqQHUdE4Q
  9. token_type:Bearer
  10. expires_in:1
  11. scope:openid profile
  12. state:OpenIdConnect.AuthenticationProperties=Tl--AjNJpswyb_R1ytC6SqEKnWP5FWe969jAIK-tPHj7l5bCYieg5fffC111-Bjur08jIafy5-DNg2ESrenp71it4OBCLnUsLXPbFGxlsT6jWwsTmRgJf5HxG-HtsTZm2iIwDkFl2P4GmlUt7GAl8gMuTNlaLqB3M-RuJ2prt603WzMQ
  13. session_state:UDOKlCOQmRPUjrKy2bRKz-erQ9Ze4jkre7FwspSAZBA.d02260a76d5c74285e125e59531cea07

注意这一步会返回一个 302 的 Location 头,并且是 HTTP ?

  1. cache-control:no-cache
  2. content-length:0
  3. date:Sun, 04 Jun 2017 07:10:05 GMT
  4. eagleid:3adc014214965602048883069e
  5. expires:-1
  6. location:http://p2.xxx.cn
  7. pragma:no-cache
  8. server:Tengine
  9. set-cookie:OpenIdConnect.nonce.nC4ZwLkiOvWjmFbe4uMezWn3Ot8OR5Q%2FEKWIPNawETw%3D=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT
  10. set-cookie:_pms_cookies=GKjrW_Lmfe3Iek_fsJ0zN9CeIQWNuawbZSAi_tl1yl3q8CT2BCqNzk7rDYrsoJGmfE_tRYN7eccbe34g4TKJjBTSOeMXbdj-JYa249ypqj_zO6spFIoCbchvtMlFUct5ygIbs9a5QVD1FdfZh6oUMFBE283N6EENqX6SxAqv1KfIrrkEyAq2vvwtrnH6uRDcva4vfvgj5777VaXHl-DGQWRy5ET1xusxwT6rx8sA_39QPKxmLeqvoEaz1JRl_pXkBwndcmAmem1g12x1J8m5oW1jBB0sF-fcVCEw737SshYAgOLs42Gb6f-KfOZToqtvf-jkjgHKDM_FgoJjigYOGG3Jbcg158wnbPhBLCukDx1-V3gHLpaKVuiv4kPVzNsQouI27AplfJUbCYQK9KAgzpAIiQXpeGW4AGCfHgHiL_txBNCRoWLRM02xvetHlvmW3vxqBu-qTa_fnYeCFd8DcSJLHcyyOwVGkI8eQEIDzAAmRvy9qYetFRhJo75_SnxK73sHw0OCzM9jX-cFt1_5X1AwXK52QBKwgtfg8Ehxtn5aKwoyEQ3SgJQOMjO1W-AK1pzPN9fbNG-zMhXxN22V7srHxOS5J8s9_w0kZKU_vTjqr8-UaGtj-ed09ik-CpfCZvYOH3sKFIa3Yb_HeOt6GnSviaML1pULaXYR0qKxsOwL2yXyfRxsZb95TGUZ9e8wVvb5AGlxVAZD6_NWlU5qxTqss7fR3vAVbFJyWDcnZ_qEP4iu2yhXuZfplsnDSB8ZO_7JEUJKEKG3AEjsaX0c0eJAc0gJEQ5bx7uujGIUe1mpGhz6AwaLXHnbY_mzgA2HFXFLaqL_l6vwbLJzg8khzqOUT8sF0d91yGco6xxxb_tcLWFURT4z3e6i2Nz0KOpQkt5R8U4TiM41khXbpfiRxsWetc-TunteIv0iVtw3K1My7-qJOeSJn_JvDtnTxaesEiMbaMcGGkyGF_Ew33kSVrO3Ooiiv3qpb2oLLCz5CQ3gxStFCxpf4_ga69rCVQZwnY3-OX4r1pUq-1ObvQBuM055c2jCyhK5EGcd0aN7tu5yCCVLcIsjVLYBmCt-fa2Hkw_qgy6e6-0T07gLPB56k7_O4dm7qI7DbtmBEVR5LYPIA3LxK0Rpsfza0Uj9ELgubA6LP7GhMD313_mIC9DMAjZ3S2jpiuENqm8FsYsLPBKjSWBDCPbI9hHwEl1fBhSoaMxhNSaLdIj88Y5tBADrV0jMgFk9n2Xnzxr8WIMlczvWcFYLoDV6W1shGdxxsDpLK6XLYtzu2hxtm26z1Zhn41LNPuOTUpOK8iC_9J68lUW61mHJbYtWBTmKgXe6IssWegbfdtRLFBRccsWSqIBYtWQtEccTFtzmX4IgBqwCHpOCIVAg7F1m3zV-cI2AfpLccceSGbONTmdOl9dmye0EgW45Mqkz4gAqBfHwkGw8EyiBV9oIUY5dwB3RcrJx9MQlF7iLRMpnbKeVxBePtiEmkc4cn81CPkxjS1PvhH1EljWtHi9OKXKeWzoExnWtVbdHJxe2mcgvNcmqfrPj-R3DWfN83pqNdymqVpqsjZFbZv2UmQlZ8RJxMAqIPqihdA5iYxWzjhtINcrvSRY6qw8fN392t83_1in0XJCHkIO5MJnNYbHhaX7RbnifvXn1Lkg2NwvjAMrl1b8EEq-AO2pqt_XvgAThvv8Khrcwon-RQxmLKVrZPpOv7O-vaHoLsTr2inclMRvwZ_b_w3WMI5G9CAU8mD8eGco1BnkSK8EL78-j57NTH3kXnro6DsA4vgv57a_QuTxXi_DsMLcK5xFDJzohSYzI4DPDjgyuWItztGgk6pAn_ScOkGJ8iMiMaAKH0kxe0g4hjoUSfsS5-SSfAe7RnhZo-WNMn3x6Iz6S7vi9mKttfBRLiKyyPe1tS3ULngJEMukZfR90tUVD1V-yRf1Td1oX08-8iIf1H_qQgLvy37_glhrQRnJOVnufbTGmBTrfJdf482TGhn5HxEOKcaXYKHSU259IegMjT0ikzrxXkCVoI-M1kBuEYtBKCvG1gPH8vO1H710GNzPGq2ZCXBFtNFPsegmx-WXviJd_-B3nFrv_N0w_op0EBZH0Zxel_ZJzkPWzs7zDMRA_qVKjjeVDFDawOK2jKfchsQn4jWCXEYRjn0OpdWb2Hq0PmLvhFPcSgGxPOs6StdcHUGIkwoERzPr20mGj4ZBM9R7krYjjbo6Lddg-Pkvu503E07J9GZMnJ97lvbSVZeckrdFXd2btmh1aJI_qg_DCWwovhKIImN-l-IShEFkQjEBwei9nIiik05qjnU3twlVVIqRaPwV9UUXPODV-xz-oXh0CeN1QKNVAHV8-uoyfzF6F1tQ1Fkv2du_AvEFYySTqqAZVcmXGY6g0ESntPJ4bSYZ-CD3Sk7PxUvJpnQoXgtVzDlqRQeTr2ltqo5QFMyIuTEOCk1alYy-crWQi6Y7-iDHdNtDkYfaVWlYy4mHavmZ9mE5VhIR69UEvRGw2c1D0sNdkBd15EzRS2jA5KGI56bTjNElT9aJOwnPyHQUTJ5I; path=/; HttpOnly
  11. status:302
  12. timing-allow-origin:*
  13. via:cache5.l2cm10-1[157,0], cache2.cn242[166,0]
  14. x-powered-by:ASP.NET

第三步:

根据 Location 的地址跳转 ,这个时候发现 并不是 HTTPS

问题分析

本能的认为是 Idsrv 的 Client 配置回调地址问题 ,后面查阅 Idsrv 源码发现跟授权的 RedirectUri 并没有什么关系(OIDC 是兼容 OAuth 2.0 的),后面查看了客户端的源码(https://github.com/aspnet/AspNetKatana/blob/dev/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs)

  1. /// <summary>
  2. /// Handles SignIn
  3. /// </summary>
  4. /// <returns></returns>
  5. protected override async Task ApplyResponseChallengeAsync()
  6. {
  7. if (Response.StatusCode == )
  8. {
  9. AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode);
  10. if (challenge == null)
  11. {
  12. return;
  13. }
  14.  
  15. // order for redirect_uri
  16. // 1. challenge.Properties.RedirectUri
  17. // 2. CurrentUri
  18. AuthenticationProperties properties = challenge.Properties;
  19. if (string.IsNullOrEmpty(properties.RedirectUri))
  20. {
  21. properties.RedirectUri = CurrentUri;
  22. }
  23.  
  24. // this value will be passed to the AuthorizationCodeReceivedNotification
  25. if (!string.IsNullOrWhiteSpace(Options.RedirectUri))
  26. {
  27. properties.Dictionary.Add(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey, Options.RedirectUri);
  28. }
  29.  
  30. if (_configuration == null)
  31. {
  32. _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.Request.CallCancelled);
  33. }
  34.  
  35. OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage
  36. {
  37. ClientId = Options.ClientId,
  38. IssuerAddress = _configuration.AuthorizationEndpoint ?? string.Empty,
  39. RedirectUri = Options.RedirectUri,
  40. RequestType = OpenIdConnectRequestType.AuthenticationRequest,
  41. Resource = Options.Resource,
  42. ResponseMode = OpenIdConnectResponseModes.FormPost,
  43. ResponseType = Options.ResponseType,
  44. Scope = Options.Scope,
  45. State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)),
  46. };
  47.  
  48. if (Options.ProtocolValidator.RequireNonce)
  49. {
  50. AddNonceToMessage(openIdConnectMessage);
  51. }
  52.  
  53. var notification = new RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(Context, Options)
  54. {
  55. ProtocolMessage = openIdConnectMessage
  56. };
  57.  
  58. await Options.Notifications.RedirectToIdentityProvider(notification);
  59.  
  60. if (!notification.HandledResponse)
  61. {
  62. string redirectUri = notification.ProtocolMessage.CreateAuthenticationRequestUrl();
  63. if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute))
  64. {
  65. _logger.WriteWarning("The authenticate redirect URI is malformed: " + redirectUri);
  66. }
  67. Response.Redirect(redirectUri);
  68. }
  69. }
  70.  
  71. return;
  72. }

默认是取 Properties.RedirectUri 的地址否则自动获得当前请求的 CurrentUri

  1. private string CurrentUri
  2. {
  3. get
  4. {
  5. return Request.Scheme +
  6. Uri.SchemeDelimiter +
  7. Request.Host +
  8. Request.PathBase +
  9. Request.Path +
  10. Request.QueryString;
  11. }
  12. }

由于我们使用的负载时在LB层做的,所以默认获得的地址是 HTTP的,那么为什么 Properties.RedirectUri 获取是哪里的数据呢 ?

  1. private readonly IOwinContext _context;
  2. ...
  3.  
  4. /// <summary>
  5. /// Find response challenge details for a specific authentication middleware
  6. /// </summary>
  7. /// <param name="authenticationType">The authentication type to look for</param>
  8. /// <param name="authenticationMode">The authentication mode the middleware is running under</param>
  9. /// <returns>The information instructing the middleware how it should behave</returns>
  10. public AuthenticationResponseChallenge LookupChallenge(string authenticationType, AuthenticationMode authenticationMode)
  11. {
  12. if (authenticationType == null)
  13. {
  14. throw new ArgumentNullException("authenticationType");
  15. }
  16.  
  17. AuthenticationResponseChallenge challenge = _context.Authentication.AuthenticationResponseChallenge;
  18. bool challengeHasAuthenticationTypes = challenge != null && challenge.AuthenticationTypes != null && challenge.AuthenticationTypes.Length != ;
  19. if (challengeHasAuthenticationTypes == false)
  20. {
  21. return authenticationMode == AuthenticationMode.Active ? (challenge ?? new AuthenticationResponseChallenge(null, null)) : null;
  22. }
  23. foreach (var challengeType in challenge.AuthenticationTypes)
  24. {
  25. if (string.Equals(challengeType, authenticationType, StringComparison.Ordinal))
  26. {
  27. return challenge;
  28. }
  29. }
  30. return null;
  31. }

也就是说在 401 状态码的情况下,会获取  _context.Authentication.AuthenticationResponseChallenge 对象时候为 null ,并不是客户端配置项,最后突然想到可能是 Idsrv 的拦截器里配置的(https://github.com/IdentityServer/IdentityServer3.Extensions.Mvc/blob/master/source/IdentityServer3.Extensions.Mvc/IdentityServer3.Extensions.Mvc/Filters/IdentityServerFullLoginAttribute.cs)

  1. public class IdentityServerFullLoginAttribute : OwinAuthenticationAttribute
  2. {
  3. public IdentityServerFullLoginAttribute()
  4. : base(Constants.PrimaryAuthenticationType)
  5. {
  6. this.Order = ;
  7. }
  8.  
  9. public override void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
  10. {
  11. var statusCodeResult = filterContext.Result as HttpStatusCodeResult;
  12. if (statusCodeResult != null && statusCodeResult.StatusCode == )
  13. {
  14. var ctx = filterContext.HttpContext.Request.GetOwinContext();
  15. var url = ctx.Environment.CreateSignInRequest(new SignInMessage
  16. {
  17. ReturnUrl = filterContext.HttpContext.Request.Url.AbsoluteUri
  18. });
  19. filterContext.Result = new RedirectResult(url);
  20. }
  21. }
  22. }

解决方案

1.) 客户单强制设置返回 302 与 URL 或 强制给 Properties.RedirectUri 赋值

  1. public class Startup
  2. {
  3. private static readonly Logger logger = LogManager.GetCurrentClassLogger();
  4. /// <summary>
  5. /// 启动类配置
  6. /// </summary>
  7. /// <param name="app"></param>
  8. public void Configuration(IAppBuilder app)
  9. {
  10. //忽略SSL证书,安全验证
  11. //ServicePointManager.ServerCertificateValidationCallback += delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
  12. //{
  13. // return true;
  14. //};
  15. // configuring Redis
  16. GlobalHost.DependencyResolver.UseRedis(new RedisScaleoutConfiguration(CacheSetting.Redis, "SignalR") { Database = });
  17. //configuring the OpenID Connect authentication middleware
  18. app.UseCookieAuthentication(new CookieAuthenticationOptions
  19. {
  20. AuthenticationType = "Cookies",
  21. });
  22. app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
  23. {
  24. // Set expiration time to 8 hours
  25. ProtocolValidator = new OpenIdConnectProtocolValidator()
  26. {
  27. NonceLifetime = new TimeSpan(, , , )
  28. },
  29. Authority = IdsvSetting.Authority,
  30. ClientId = IdsvSetting.ClientId,
  31. Scope = "openid profile",
  32. ResponseType = "id_token token",
  33. RedirectUri = IdsvSetting.RedirectUri,
  34. SignInAsAuthenticationType = "Cookies",
  35. UseTokenLifetime = false,
  36. Notifications = new OpenIdConnectAuthenticationNotifications
  37. {
  38. SecurityTokenValidated = async n =>
  39. {
  40. try
  41. {
  42. var id = n.AuthenticationTicket.Identity;
  43. var nid = new ClaimsIdentity(id.AuthenticationType);
  44. // keep the id_token for logout
  45. nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
  46. // add access token for sample API
  47. nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken));
  48. // keep track of access token expiration
  49. nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString()));
  50. //获得用户信息
  51. // var client = new UserInfoClient(new Uri(n.Options.Authority + "/connect/userinfo"), n.ProtocolMessage.AccessToken);
  52. //var userInfo = await client.GetAsync();
  53. //var user = userInfo.JsonObject.Last.First.ToString().DeserializeJson<XHotelOAuth2UserInfoResponse>(System.Text.Encoding.UTF8);
  54. var userInfoClient = new UserInfoClient(new Uri(n.Options.Authority + "/connect/userinfo"), n.ProtocolMessage.AccessToken);
  55. var userInfo = await userInfoClient.GetAsync();
  56. var user = userInfo.JsonObject.Last.First.ToString().DeserializeJson<XHotelOAuth2UserInfoResponse>(System.Text.Encoding.UTF8);
  57. ...
  58.  
  59. n.AuthenticationTicket = new AuthenticationTicket(nid, n.AuthenticationTicket.Properties);
  60. ////清空 OpenIdConnect 开头的 Cookies
  61. foreach (var item in HttpContext.Current.Request.Cookies.AllKeys)
  62. {
  63. if (item.Contains("OpenIdConnect", StringComparison.OrdinalIgnoreCase))
  64. {
  65. HttpCookie cookie = HttpContext.Current.Request.Cookies[item];
  66. cookie.Expires = DateTime.Now.AddDays(-);
  67. HttpContext.Current.Response.Cookies.Add(cookie);
  68. }
  69. }
  70. HttpContext.Current.Response.AddHeader("Location", IdsvSetting.RedirectUri);
  71. }
  72. catch (Exception ex)
  73. {
  74. ex.ToExceptionless().MarkAsCritical().Submit();
  75. logger.Error(ex, "UseOpenIdConnectAuthentication: " + ex.Message);
  76. }
  77. },
  78. RedirectToIdentityProvider = n =>
  79. {
  80. if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
  81. {
  82. var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
  83. if (idTokenHint != null)
  84. {
  85. n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
  86. }
  87. }
  88. return Task.FromResult();
  89. },
  90. AuthenticationFailed = (context) =>
  91. {
  92. if (context.Exception is OpenIdConnectProtocolInvalidNonceException && context.Exception.Message.ContainsAny(new string[] { "IDX10316", "IDX10311" }))
  93. {
  94. logger.Warn("OpenIdConnectProtocolInvalidNonce expired, reauthenticating...");
  95. context.HandleResponse();
  96. //context.Response.Redirect("/Error.aspx?message=" + context.Exception.Message);
  97. context.Response.Redirect(context.Request.Uri.PathAndQuery);
  98. }
  99. return Task.FromResult();
  100. },
  101. }
  102. });
  103. }
  104. }

2.) MVC 拦截器里设置 Properties.RedirectUri

  1. public class TokenAuthorizeFilter : AuthorizeAttribute
  2. {
  3. public override void OnAuthorization(AuthorizationContext context)
  4. {
  5. if (!context.HttpContext.User.Identity.IsAuthenticated)
  6. {
  7. #if !DEBUG
  8. HttpContext.Current.GetOwinContext().Authentication.Challenge(new AuthenticationProperties
  9. {
  10. RedirectUri = context.HttpContext.Request.Url.ToString().Replace("http", "https")
  11. });
  12. #endif
  13. // 401 who are you? go login and then try again
  14. context.Result = new HttpUnauthorizedResult();
  15. }
  16. //如果 session 不存在,清除 openid
  17. // context.RequestContext.HttpContext.GetOwinContext().Authentication.SignOut();
  18. // context.Result = new RedirectResult("/home?returnUrl=" + HttpUtility.UrlEncode(HttpContext.Current.Request.Url.AbsoluteUri));
  19. }
  20. }

REFER:
https://github.com/IdentityServer/IdentityServer3.Extensions.Mvc
https://github.com/aspnet/AspNetKatana
干掉状态:从session到token
https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513566&idx=1&sn=a2688cadbe9c8042ff1abbdf04a8bd5e&chksm=80d67a1db7a1f30b28b93ed2ab29edfbf982b780433e4bfd178e3cc52cb1f9100cc8f923db4f#rd

关于 OpenIdConnect 认证启用 HTTPS 回调 RedirectUri 不生效问题的更多相关文章

  1. 【转】Tomcat启用HTTPS协议配置过程

    转载请注明出处: http://blog.csdn.net/gane_cheng/article/details/53001846 http://www.ganecheng.tech/blog/530 ...

  2. 关于启用 HTTPS 的一些经验分享(二)

    转载: 关于启用 HTTPS 的一些经验分享(二) 几天前,一位朋友问我:都说推荐用 Qualys SSL Labs 这个工具测试 SSL 安全性,为什么有些安全实力很强的大厂家评分也很低?我认为这个 ...

  3. 关于启用 HTTPS 的一些经验分享(一)

    转载: 关于启用 HTTPS 的一些经验分享(一) 随着国内网络环境的持续恶化,各种篡改和劫持层出不穷,越来越多的网站选择了全站 HTTPS.就在今天,免费提供证书服务的 Let's Encrypt ...

  4. 【转】关于启用 HTTPS 的一些经验分享

    随着国内网络环境的持续恶化,各种篡改和劫持层出不穷,越来越多的网站选择了全站 HTTPS.HTTPS 通过 TLS 层和证书机制提供了内容加密.身份认证和数据完整性三大功能,可以有效防止数据被查看或篡 ...

  5. 关于启用 HTTPS 的一些经验分享

    https://imququ.com/post/sth-about-switch-to-https.html 随着国内网络环境的持续恶化,各种篡改和劫持层出不穷,越来越多的网站选择了全站 HTTPS. ...

  6. Startssl 现在就启用 HTTPS,免费的!

    为什么要使用HTTPS 主要是为了安全,虽然没有100%的安全,但是我们可以尽量提高安全级别,目前大型网站都已经使用HTTPS了 注册StartSSL 注册页面  选择国家 和 输入 邮箱 他们会通过 ...

  7. 现在就启用 HTTPS,免费的!

    现在就启用 HTTPS,免费的! 现在,你应该能在访问https://konklone.com的时候,在地址栏里看到一个漂亮的小绿锁了,因为我把这个网站换成了HTTPS协议.一分钱没花就搞定了. 为什 ...

  8. 转载 关于启用HTTPS的一些经验分享

    本文转载自  https://imququ.com/post/sth-about-switch-to-https.html 随着国内网络环境的持续恶化,各种篡改和劫持层出不穷,越来越多的网站选择了全站 ...

  9. Tomcat启用HTTPS协议配置过程

    Article1较为简洁,Article2较为详细,测试可行. Article1 概念简介 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问 ...

随机推荐

  1. linux内核链表使用

    原文链接:http://blog.csdn.net/xnwyd/article/details/7359373 Linux内核链表的核心思想是:在用户自定义的结构A中声明list_head类型的成员p ...

  2. 【设计模式】Javascript设计模式——状态模式(行为型)

    注:这个模式是非常聪明的,很有点数学中组合的意思,现在,来看下这个模式是怎么个思想. 问题提出:假如某个操作有三种可能,分别为1,2,3,还可能是组合,比如先执行1,再执行2或者先执行2再执行3或者1 ...

  3. 使用VBA宏批量修改表格

    一.批量修改表格,实现所有表格的宽度根据窗口自动调整. Sub test() ' ' test 宏 ' ' Dim i As Table, N As Integer On Error Resume N ...

  4. ES基本查询

    数据准备 # 创建索引PUT /lib1{  "settings": {    "number_of_shards": 5   , "number_o ...

  5. express 错误处理

    原谅我的无知,之前学习express时,没想过需要错误处理.app.js也没认真看. 现在做具体的项目时,需要考虑到出错的情况. 其实有两种: 1.nodejs是单线程,如果挂掉了,网站就会崩溃,需要 ...

  6. nodeclub config

    配置文件,本来想着分成好几个文件,放在一个文件夹中,后来觉得也没必要,原因是,配置文件看一遍也就记住了,分开反而显得繁琐,注释写清楚就好. // 路径模块 var path = require('pa ...

  7. html,css,jquery,JavaScript

    1.全选 (当点击checkall按钮时,选中所有checkbox用prop全选上)function checkAll() { $(':checkbox').prop('checked', true) ...

  8. FormatSQL

    核心提示:在一些论坛,常看到有人拼接SQL的时候,喜欢直接硬拼,结果就是出现一大堆加号和单引号,不仅写起来麻烦(你得小心该连续写多少个单引号),SQL的可读性也相当差....稍微好一点的方法是,使用Q ...

  9. CentOS6.5分区与文件系统

    1 分区介绍 inux分区不同于windows,linux下硬盘设备名为(IDE硬盘为hdx(x为从a—d)因为IDE硬盘最多四个,SCSI,SATA,USB硬盘为sdx(x为a—z)),硬盘主分区最 ...

  10. Cannot retrieve metalink for repository: epel/x86_64. Please verify its path and try again 问题分析

    Cannot retrieve metalink for repository: epel/x86_64. Please verify its path and try again Loaded pl ...