<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring Security OAuth2整合企業(yè)微信掃碼登錄

          共 5861字,需瀏覽 12分鐘

           ·

          2022-06-20 23:45

          現(xiàn)在很多企業(yè)都接入了企業(yè)微信,作為私域社群工具,企業(yè)微信開(kāi)放了很多API,可以打通很多自有的應(yīng)用。既然是應(yīng)用,那肯定需要做登錄。正好企業(yè)微信提供了企業(yè)微信掃碼授權(quán)登錄功能,而且號(hào)稱使用了OAuth,正好拿這個(gè)檢驗(yàn)一下Spring Security OAuth2專欄的威力。

          正當(dāng)我興致勃勃打開(kāi)文檔學(xué)習(xí)的時(shí)候,臉上笑容逐漸消失,這確定是OAuth的嗎?

          參數(shù)都變了,跟OAuth(不管是1.0還是2.0)規(guī)定不一樣,然而這還不是最離譜的。按正常OAuth2的要求,拿到code之后就可以換access_token了是吧?企業(yè)微信的access_token居然和上面掃碼獲取code這一步完全無(wú)關(guān),甚至獲取access_token才是第一步!

          ?

          而且這個(gè)access_token接口,你還不能頻繁調(diào)用,要緩存起來(lái)公用。

          那費(fèi)了半天勁兒去拿code有啥用呢?

          居然這個(gè)code是拿用戶信息的,不得不說(shuō),我服了!這也就算了,命名上能不能走點(diǎn)心,一會(huì)兒下劃線,一會(huì)兒駝峰:

          {
             "errcode"0,
             "errmsg""ok",
             "OpenId":"OPENID",
             "DeviceId":"DEVICEID",
             "external_userid":"EXTERNAL_USERID"
          }

          這個(gè)JSON風(fēng)格,果然是大廠,講究人,一個(gè)JSON要三個(gè)人來(lái)寫(xiě)才體面!反序列化的時(shí)候我還得給你寫(xiě)一個(gè)兼容,這是要拉滿我的KPI是吧?算了,忍忍吧,老板就要這個(gè)功能,它就是一坨翔,做開(kāi)發(fā)的也得含淚吃下去,干!

          環(huán)境準(zhǔn)備

          準(zhǔn)備一個(gè)內(nèi)網(wǎng)穿透

          開(kāi)發(fā)微信相關(guān)的應(yīng)用都需要搞一個(gè)內(nèi)網(wǎng)穿透,在我往期的文章都有介紹。搞一個(gè)映射域名出來(lái),就像下面這樣:

          http://invybj.natappfree.cc -> 127.0.0.1:8082 

          invybj.natappfree.cc會(huì)映射到我本地的8082端口,也就是我本地要開(kāi)發(fā)應(yīng)用的端口。

          創(chuàng)建應(yīng)用

          首先去企業(yè)微信管理后臺(tái)創(chuàng)建一個(gè)應(yīng)用,如圖:

          ?

          圖里的參數(shù)AgentIdSecret要記下來(lái)備用。

          還有一個(gè)企業(yè)微信的corpid,你可以從下面這個(gè)位置拿到,也要記下來(lái)備用。

          配置內(nèi)網(wǎng)穿透域名

          創(chuàng)建應(yīng)用這一頁(yè)往下拉到頁(yè)面底端,你會(huì)看到:

          點(diǎn)擊已啟用進(jìn)入下面這個(gè)頁(yè)面:

          這里配置你授權(quán)登錄應(yīng)用生產(chǎn)的正式域名或者上面內(nèi)網(wǎng)穿透的域名,注意只配置域名,而且不能使用localhost。

          ?

          其實(shí)我感覺(jué)改寫(xiě)hosts文件也能用啊,你可以試一試。

          到這里環(huán)境就搞定了,接下來(lái)就開(kāi)始寫(xiě)Spring Security兼容代碼吧。

          Spring Security兼容企業(yè)微信掃碼登錄

          寫(xiě)起來(lái)太惡心了,不過(guò)對(duì)比文檔和OAuth2的流程之后其實(shí)也沒(méi)那么麻煩。我先放出我調(diào)試好的配置:

          spring:
            security:
              oauth2:
                client:
                  registration:
                    work-wechat-scan:
                      # client-id為企業(yè)微信 的企業(yè)ID
                      # 下面client-id是假的,你用你自己的企業(yè)ID
                      client-id: wwaxxxxxx
                      # client-secret企業(yè)微信對(duì)應(yīng)應(yīng)用的secret,
                      # 每個(gè)企業(yè)微信應(yīng)用都有獨(dú)立的secret,不要搞錯(cuò)
                      # 下面client-secret假的,你用你自己創(chuàng)建的企業(yè)微信應(yīng)用secret
                      client-secret:  nvzGI4Alp3zxxxxxxxKbnfTEets5W8
                      authorization-grant-type: authorization_code
                      redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
                  provider:
                    work-wechat-scan:
                      authorization-uri: https://open.work.weixin.qq.com/wwopen/sso/qrConnect
                      token-uri: https://qyapi.weixin.qq.com/cgi-bin/gettoken
                      user-info-uri: https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo

          這里client-id使用你企業(yè)微信的企業(yè)ID,client-secret使用上面創(chuàng)建應(yīng)用的secret值。

          ?

          這里的work-wechat-scan是客戶端的registrationId

          封裝企業(yè)微信拉起二維碼URL

          我們期望的是保持Spring Security OAuth2的風(fēng)格,當(dāng)我訪問(wèn):

          http://invybj.natappfree.cc/oauth2/authorization/work-wechat-scan

          會(huì)重定向到企業(yè)微信掃碼登錄鏈接,格式為:

          https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid=CORPID&agentid=AGENTID&redirect_uri=REDIRECT_URI&state=STATE

          這個(gè)和以前胖哥實(shí)現(xiàn)微信網(wǎng)頁(yè)授權(quán)的原理差不多,都是通過(guò)改造OAuth2AuthorizationRequestResolver接口來(lái)實(shí)現(xiàn),只需要實(shí)現(xiàn)一個(gè)Consumer<OAuth2AuthorizationRequest.Builder>就行了。

          邏輯是:client_id替換為appid,增加一個(gè)agentid參數(shù),連帶redirect_uristate四個(gè)參數(shù)之外的其它OAuth2參數(shù)全干掉,拼接成上面的URL。

          這么寫(xiě):

          把這個(gè)Consumer配置到DefaultOAuth2AuthorizationRequestResolver就行了。

          適配OAuth2獲取access_token

          經(jīng)過(guò)這一步掃碼拿到code就不成問(wèn)題了,按照OAuth2該拿access_token了,需要自定義一個(gè)函數(shù)式接口:

          Converter<OAuth2AuthorizationCodeGrantRequest, RequestEntity<?>>

          也就是利用OAuth2AuthorizationCodeGrantRequest生成RestTemplate需要的請(qǐng)求對(duì)象RequestEntity<?>。按照企業(yè)微信獲取access_token的文檔,這樣自定義:

          把這個(gè)配置到DefaultAuthorizationCodeTokenResponseClient就行了。

          access_token的緩存,我放在了下一步進(jìn)行解決。

          適配獲取用戶信息

          codeaccess_token都拿到了,最后一步獲取用戶的信息。這里是比較麻煩的因?yàn)楂@取access_token后并沒(méi)有直接提供將code傳遞給OAuth2UserService的方法。最后發(fā)現(xiàn)OAuth2AccessTokenResponseadditionalParameters屬性可以傳遞到OAuth2UserService,于是就利用代理模式改造了OAuth2AccessTokenResponseClient來(lái)實(shí)現(xiàn):

          自定義企業(yè)微信OAuth2UserService

          這個(gè)和微信網(wǎng)頁(yè)授權(quán)我封裝的差不多,改下參數(shù)封裝成URI交給RestTemplate請(qǐng)求企業(yè)微信API。惡心的是要反序列化兼容三個(gè)微信研發(fā)工程師寫(xiě)的一個(gè)JSON

          @Data
          public class WorkWechatOAuth2User implements OAuth2User {
              private Set<GrantedAuthority> authorities;
              private Integer errcode;
              private String errmsg;
              @JsonAlias("OpenId")
              private String openId;
              @JsonAlias("UserId")
              private String userId;
          }

          收尾

          拿到用戶信息后,就結(jié)束了,你實(shí)現(xiàn)一個(gè)AuthenticationSuccessHandler來(lái)保證登錄憑證和你平臺(tái)一致,無(wú)論是cookie還是JWT,最后把它配置到這里:

          httpSecurity.oauth2Login()
              .successHandler(AuthenticationSuccessHandler successHandler)

          試一下效果

          ?

          務(wù)必使用域名進(jìn)行訪問(wèn),不要使用localhost或者IP。

          訪問(wèn)http://invybj.natappfree.cc/login,這里是內(nèi)網(wǎng)穿透域名,出現(xiàn):

          企業(yè)微信掃碼登錄的地址其實(shí)就是http://invybj.natappfree.cc/oauth2/authorization/work-wechat-scan。點(diǎn)擊跳轉(zhuǎn)到掃碼頁(yè)面:

          然后用你對(duì)應(yīng)的企業(yè)微信APP掃碼,企業(yè)和用戶要和申請(qǐng)應(yīng)用的一致。掃碼后:

          這個(gè)就是Spring Security 封裝的用戶認(rèn)證信息Authentication對(duì)象,是真正的登錄,這里我沒(méi)有注入權(quán)限,你需要在企業(yè)微信的OAuth2UserService實(shí)現(xiàn)中注入權(quán)限和更多的信息。

          我們創(chuàng)建了一個(gè)高質(zhì)量的技術(shù)交流群,與優(yōu)秀的人在一起,自己也會(huì)優(yōu)秀起來(lái),趕緊點(diǎn)擊加群,享受一起成長(zhǎng)的快樂(lè)。另外,如果你最近想跳槽的話,年前我花了2周時(shí)間收集了一波大廠面經(jīng),節(jié)后準(zhǔn)備跳槽的可以點(diǎn)擊這里領(lǐng)取!

          推薦閱讀

          ··································

          你好,我是程序猿DD,10年開(kāi)發(fā)老司機(jī)、阿里云MVP、騰訊云TVP、出過(guò)書(shū)創(chuàng)過(guò)業(yè)、國(guó)企4年互聯(lián)網(wǎng)6年。從普通開(kāi)發(fā)到架構(gòu)師、再到合伙人。一路過(guò)來(lái),給我最深的感受就是一定要不斷學(xué)習(xí)并關(guān)注前沿。只要你能堅(jiān)持下來(lái),多思考、少抱怨、勤動(dòng)手,就很容易實(shí)現(xiàn)彎道超車!所以,不要問(wèn)我現(xiàn)在干什么是否來(lái)得及。如果你看好一個(gè)事情,一定是堅(jiān)持了才能看到希望,而不是看到希望才去堅(jiān)持。相信我,只要堅(jiān)持下來(lái),你一定比現(xiàn)在更好!如果你還沒(méi)什么方向,可以先關(guān)注我,這里會(huì)經(jīng)常分享一些前沿資訊,幫你積累彎道超車的資本。

          點(diǎn)擊領(lǐng)取2022最新10000T學(xué)習(xí)資料
          瀏覽 46
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成年人视频免费在线观看大香蕉 | 三级久久电影 | 婷婷丁香成人网站 | 国产主播91 | 丁香五月婷婷综合 |