zoukankan      html  css  js  c++  java
  • 关于 OpenIdConnect 认证启用 HTTPS 回调 RedirectUri 不生效问题

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

    OpenID Connect 认证流程

    第一步:

    请求构造授权页

    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
    Request Method:GET
    Status Code:200 
    Remote Address:222.186.49.226:443
    Referrer Policy:no-referrer-when-downgrade
    :authority:sso.xxx.cn
    :method:GET
    :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
    :scheme:https
    accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    accept-encoding:gzip, deflate, sdch, br
    accept-language:zh-CN,zh;q=0.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
    referer:https://sso.xxx.cn/login?signin=249b0aeaa528d65e2fabdac9f695167d
    upgrade-insecure-requests:1
    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给客户端的机制。

    Request URL:https://p2.xxx.cn/
    Request Method:POST
    Status Code:302 
    Remote Address:58.220.27.80:443
    Referrer Policy:no-referrer-when-downgrade
    
    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

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

    cache-control:no-cache
    content-length:0
    date:Sun, 04 Jun 2017 07:10:05 GMT
    eagleid:3adc014214965602048883069e
    expires:-1
    location:http://p2.xxx.cn
    pragma:no-cache
    server:Tengine
    set-cookie:OpenIdConnect.nonce.nC4ZwLkiOvWjmFbe4uMezWn3Ot8OR5Q%2FEKWIPNawETw%3D=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT
    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
    status:302
    timing-allow-origin:*
    via:cache5.l2cm10-1[157,0], cache2.cn242[166,0]
    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)

            /// <summary>
            /// Handles SignIn
            /// </summary>
            /// <returns></returns>
            protected override async Task ApplyResponseChallengeAsync()
            {
                if (Response.StatusCode == 401)
                {
                    AuthenticationResponseChallenge challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode);
                    if (challenge == null)
                    {
                        return;
                    }
    
                    // order for redirect_uri
                    // 1. challenge.Properties.RedirectUri
                    // 2. CurrentUri
                    AuthenticationProperties properties = challenge.Properties;
                    if (string.IsNullOrEmpty(properties.RedirectUri))
                    {
                        properties.RedirectUri = CurrentUri;
                    }
    
                    // this value will be passed to the AuthorizationCodeReceivedNotification
                    if (!string.IsNullOrWhiteSpace(Options.RedirectUri))
                    {
                        properties.Dictionary.Add(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey, Options.RedirectUri);
                    }
    
                    if (_configuration == null)
                    {
                        _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.Request.CallCancelled);
                    }
    
                    OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage
                    {
                        ClientId = Options.ClientId,
                        IssuerAddress = _configuration.AuthorizationEndpoint ?? string.Empty,
                        RedirectUri = Options.RedirectUri,
                        RequestType = OpenIdConnectRequestType.AuthenticationRequest,
                        Resource = Options.Resource,
                        ResponseMode = OpenIdConnectResponseModes.FormPost,
                        ResponseType = Options.ResponseType,
                        Scope = Options.Scope,
                        State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)),
                    };
    
                    if (Options.ProtocolValidator.RequireNonce)
                    {
                        AddNonceToMessage(openIdConnectMessage);
                    }
    
                    var notification = new RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(Context, Options)
                    {
                        ProtocolMessage = openIdConnectMessage
                    };
    
                    await Options.Notifications.RedirectToIdentityProvider(notification);
    
                    if (!notification.HandledResponse)
                    {
                        string redirectUri = notification.ProtocolMessage.CreateAuthenticationRequestUrl();
                        if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute))
                        {
                            _logger.WriteWarning("The authenticate redirect URI is malformed: " + redirectUri);
                        }
                        Response.Redirect(redirectUri);
                    }
                }
    
                return;
            }

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

    private string CurrentUri
            {
                get
                {
                    return Request.Scheme +
                           Uri.SchemeDelimiter +
                           Request.Host +
                           Request.PathBase +
                           Request.Path +
                           Request.QueryString;
                }
            }

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

    private readonly IOwinContext _context;
    ...
    
            /// <summary>
            /// Find response challenge details for a specific authentication middleware
            /// </summary>
            /// <param name="authenticationType">The authentication type to look for</param>
            /// <param name="authenticationMode">The authentication mode the middleware is running under</param>
            /// <returns>The information instructing the middleware how it should behave</returns>
            public AuthenticationResponseChallenge LookupChallenge(string authenticationType, AuthenticationMode authenticationMode)
            {
                if (authenticationType == null)
                {
                    throw new ArgumentNullException("authenticationType");
                }
    
                AuthenticationResponseChallenge challenge = _context.Authentication.AuthenticationResponseChallenge;
                bool challengeHasAuthenticationTypes = challenge != null && challenge.AuthenticationTypes != null && challenge.AuthenticationTypes.Length != 0;
                if (challengeHasAuthenticationTypes == false)
                {
                    return authenticationMode == AuthenticationMode.Active ? (challenge ?? new AuthenticationResponseChallenge(null, null)) : null;
                }
                foreach (var challengeType in challenge.AuthenticationTypes)
                {
                    if (string.Equals(challengeType, authenticationType, StringComparison.Ordinal))
                    {
                        return challenge;
                    }
                }
                return null;
            }

    也就是说在 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)

    public class IdentityServerFullLoginAttribute : OwinAuthenticationAttribute
        {
            public IdentityServerFullLoginAttribute()
                : base(Constants.PrimaryAuthenticationType)
            {
                this.Order = 1;
            }
    
            public override void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
            {
                var statusCodeResult = filterContext.Result as HttpStatusCodeResult;
                if (statusCodeResult != null && statusCodeResult.StatusCode == 401)
                {
                    var ctx = filterContext.HttpContext.Request.GetOwinContext();
                    var url = ctx.Environment.CreateSignInRequest(new SignInMessage
                    {
                        ReturnUrl = filterContext.HttpContext.Request.Url.AbsoluteUri
                    });
                    filterContext.Result = new RedirectResult(url);
                }
            }
        }

    解决方案

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

     public class Startup
        {
            private static readonly Logger logger = LogManager.GetCurrentClassLogger();
            /// <summary>
            /// 启动类配置
            /// </summary>
            /// <param name="app"></param>
            public void Configuration(IAppBuilder app)
            {
                //忽略SSL证书,安全验证
                //ServicePointManager.ServerCertificateValidationCallback += delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
                //{
                //    return true;
                //};
                // configuring Redis
                GlobalHost.DependencyResolver.UseRedis(new RedisScaleoutConfiguration(CacheSetting.Redis, "SignalR") { Database = 3 });
                //configuring the OpenID Connect authentication middleware
                app.UseCookieAuthentication(new CookieAuthenticationOptions
                {
                    AuthenticationType = "Cookies",
                });
                app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
                {
                    // Set expiration time to 8 hours
                    ProtocolValidator = new OpenIdConnectProtocolValidator()
                    {
                        NonceLifetime = new TimeSpan(0, 8, 0, 0)
                    },
                    Authority = IdsvSetting.Authority,
                    ClientId = IdsvSetting.ClientId,
                    Scope = "openid profile",
                    ResponseType = "id_token token",
                    RedirectUri = IdsvSetting.RedirectUri,
                    SignInAsAuthenticationType = "Cookies",
                    UseTokenLifetime = false,
                    Notifications = new OpenIdConnectAuthenticationNotifications
                    {
                        SecurityTokenValidated = async n =>
                        {
                            try
                            {
                                var id = n.AuthenticationTicket.Identity;
                                var nid = new ClaimsIdentity(id.AuthenticationType);
                                // keep the id_token for logout
                                nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
                                // add access token for sample API
                                nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken));
                                // keep track of access token expiration
                                nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString()));
                                //获得用户信息
                                // var client = new UserInfoClient(new Uri(n.Options.Authority + "/connect/userinfo"), n.ProtocolMessage.AccessToken);
                                //var userInfo = await client.GetAsync();
                                //var user = userInfo.JsonObject.Last.First.ToString().DeserializeJson<XHotelOAuth2UserInfoResponse>(System.Text.Encoding.UTF8);
                                var userInfoClient = new UserInfoClient(new Uri(n.Options.Authority + "/connect/userinfo"), n.ProtocolMessage.AccessToken);
                                var userInfo = await userInfoClient.GetAsync();
                                var user = userInfo.JsonObject.Last.First.ToString().DeserializeJson<XHotelOAuth2UserInfoResponse>(System.Text.Encoding.UTF8);
     ...
    
                                n.AuthenticationTicket = new AuthenticationTicket(nid, n.AuthenticationTicket.Properties);
                                ////清空 OpenIdConnect 开头的 Cookies 
                                foreach (var item in HttpContext.Current.Request.Cookies.AllKeys)
                                {
                                    if (item.Contains("OpenIdConnect", StringComparison.OrdinalIgnoreCase))
                                    {
                                        HttpCookie cookie = HttpContext.Current.Request.Cookies[item];
                                        cookie.Expires = DateTime.Now.AddDays(-1);
                                        HttpContext.Current.Response.Cookies.Add(cookie);
                                    }
                                }
                                HttpContext.Current.Response.AddHeader("Location", IdsvSetting.RedirectUri);
                            }
                            catch (Exception ex)
                            {
                                ex.ToExceptionless().MarkAsCritical().Submit();
                                logger.Error(ex, "UseOpenIdConnectAuthentication: " + ex.Message);
                            }
                        },
                        RedirectToIdentityProvider = n =>
                        {
                            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);
                        },
                        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);
                        },
                    }
                });
            }
        }

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

     public class TokenAuthorizeFilter : AuthorizeAttribute
        {
            public override void OnAuthorization(AuthorizationContext context)
            {
                if (!context.HttpContext.User.Identity.IsAuthenticated)
                {
    #if !DEBUG
                    HttpContext.Current.GetOwinContext().Authentication.Challenge(new AuthenticationProperties
                    {
                        RedirectUri = context.HttpContext.Request.Url.ToString().Replace("http", "https")
                    });
    #endif
                    // 401 who are you? go login and then try again
                    context.Result = new HttpUnauthorizedResult();
                }
                //如果 session 不存在,清除 openid
                // context.RequestContext.HttpContext.GetOwinContext().Authentication.SignOut();
                // context.Result = new RedirectResult("/home?returnUrl=" + HttpUtility.UrlEncode(HttpContext.Current.Request.Url.AbsoluteUri));
            }
        }

    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

  • 相关阅读:
    【leetcode】Edit Distance (hard)
    【leetcode】 Interleaving String (hard)
    【leetcode】Regular Expression Matching (hard) ★
    【leetcode】Wildcard Matching(hard) ★ 大神太牛了
    【leetcode】 Longest Valid Parentheses (hard)★
    【leetcode】 Scramble String (hard)★
    【leetcode】Maximal Rectangle (hard)★
    【leetcode】 Unique Binary Search Trees (middle)☆
    【计算机网络】应用层1
    【leetcode】Minimum Path Sum(easy)
  • 原文地址:https://www.cnblogs.com/Irving/p/6940773.html
Copyright © 2011-2022 走看看