Spring Security如何与企业微信扫码登录无缝对接,其API功能让我惊叹不已?

2026-04-28 15:412阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2170个文字,预计阅读时间需要9分钟。

Spring Security如何与企业微信扫码登录无缝对接,其API功能让我惊叹不已?

原文代码:https://gitee.com/felord/spring-security-oauth2-tutorial/tree/wwopen/现在很多企业都接入企业微信,作为域社群工具,企业微信开放了大量的API,可以打通很多自有应用。如果是应用,则:

本文代码: gitee.com/felord/spring-security-oauth2-tutorial/tree/wwopen/

现在很多企业都接入了企业微信,作为私域社群工具,企业微信开放了很多API,可以打通很多自有的应用。既然是应用,那肯定需要做登录。正好企业微信提供了企业微信扫码授权登录功能,而且号称使用了OAuth,正好拿这个检验一下Spring Security OAuth2专栏的威力。

正当我兴致勃勃打开文档学习的时候,脸上笑容逐渐消失,这确定是OAuth的吗?

参数都变了,跟OAuth(不管是1.0还是2.0)规定不一样,然而这还不是最离谱的。按正常OAuth2的要求,拿到code之后就可以换access_token了是吧?企业微信的access_token居然和上面扫码获取code这一步完全无关,甚至获取access_token才是第一步!

而且这个access_token接口,你还不能频繁调用,要缓存起来公用。

那费了半天劲儿去拿code有啥用呢?

居然这个code是拿用户信息的,不得不说,我服了!OAuth2的123流程被整成了213。这也就算了,命名上能不能走点心,一会儿下划线,一会儿驼峰:

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

这个JSON风格,果然是大厂,讲究!一个JSON要三个人来写才体面!反序列化的时候我还得给你写一个兼容,这是要拉满我的KPI是吧?算了,忍忍吧,老板就要这个功能,它就是一坨翔,做开发的也得含泪吃下去,干!

环境准备 准备一个内网穿透

开发微信相关的应用都需要搞一个内网穿透,在我往期的文章都有介绍。搞一个映射域名出来,就像下面这样:

invybj.natappfree.cc -> 127.0.0.1:8082

invybj.natappfree.cc会映射到我本地的8082端口,也就是我本地要开发应用的端口。

Spring Security如何与企业微信扫码登录无缝对接,其API功能让我惊叹不已?

创建应用

首先去企业微信管理后台创建一个应用,如图:

图里的参数AgentIdSecret要记下来备用。

还有一个企业微信的corpid,你可以从下面这个位置拿到,也要记下来备用。

配置内网穿透域名

创建应用这一页往下拉到页面底端,你会看到:

点击已启用进入下面这个页面:

这里配置你授权登录应用生产的正式域名或者上面内网穿透的域名,注意只配置域名,而且不能使用localhost

其实我感觉改写hosts文件也能用啊,你可以试一试。

到这里环境就搞定了,接下来就开始写Spring Security兼容代码吧。

Spring Security兼容企业微信扫码登录

写起来太恶心了,不过对比文档和OAuth2的流程之后其实也没那么麻烦。我先放出我调试好的配置:

spring: security: oauth2: client: registration: work-wechat-scan: # client-id为企业微信 的企业ID # 下面client-id是假的,你用你自己的企业ID client-id: wwaxxxxxx # client-secret企业微信对应应用的secret, # 每个企业微信应用都有独立的secret,不要搞错 # 下面client-secret假的,你用你自己创建的企业微信应用secret client-secret: nvzGI4Alp3zxxxxxxxKbnfTEets5W8 authorization-grant-type: authorization_code redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}' provider: work-wechat-scan: authorization-uri: open.work.weixin.qq.com/wwopen/sso/qrConnect token-uri: qyapi.weixin.qq.com/cgi-bin/gettoken user-info-uri: qyapi.weixin.qq.com/cgi-bin/user/getuserinfo

这里client-id使用你企业微信的企业IDclient-secret使用上面创建应用的secret值。

这里的work-wechat-scan是客户端的registrationId

封装企业微信拉起二维码URL

我们期望的是保持Spring Security OAuth2的风格,当我访问:

Converter<OAuth2AuthorizationCodeGrantRequest, RequestEntity<?>>

也就是利用OAuth2AuthorizationCodeGrantRequest生成RestTemplate需要的请求对象RequestEntity<?>。按照企业微信获取access_token的文档,这样自定义:

把这个配置到DefaultAuthorizationCodeTokenResponseClient就行了。

access_token的缓存,我放在了下一步进行解决。

适配获取用户信息

codeaccess_token都拿到了,最后一步获取用户的信息。这里是比较麻烦的因为获取access_token后并没有直接提供将code传递给OAuth2UserService的方法。最后发现OAuth2AccessTokenResponseadditionalParameters属性可以传递到OAuth2UserService,于是就利用代理模式改造了OAuth2AccessTokenResponseClient来实现:

自定义企业微信OAuth2UserService

这个和微信网页授权我封装的差不多,改下参数封装成URI交给RestTemplate请求企业微信API。恶心的是要反序列化兼容三个微信研发工程师写的一个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; } 收尾

拿到用户信息后,就结束了,你实现一个AuthenticationSuccessHandler来保证登录凭证和你平台一致,无论是cookie还是JWT,最后把它配置到这里:

invybj.natappfree.cc/login这里是内网穿透域名,出现:

企业微信扫码登录的地址其实就是invybj.natappfree.cc/oauth2/authorization/work-wechat-scan。点击跳转到扫码页面:

然后用你对应的企业微信APP扫码企业和用户要和申请应用的一致。扫码后:

这个就是Spring Security 封装的用户认证信息Authentication对象,是真正的登录,这里我没有注入权限,你需要在企业微信的OAuth2UserService实现中注入权限和更多的信息。

总结

没有实现不了的,只要把原理和流程搞清楚就行。不过如果上游微信把代码写规范一些,下游何必写这么多冗余的代码。

关注公众号:Felordcn 获取更多资讯

个人博客:felord.cn

博主:码农小胖哥
出处:felord.cn
本文版权归原作者所有,不可商用,转载需要声明出处,否则保留追究法律责任的权利。如果文中有什么错误,欢迎指出。以免更多的人被误导。
标签:扫码

本文共计2170个文字,预计阅读时间需要9分钟。

Spring Security如何与企业微信扫码登录无缝对接,其API功能让我惊叹不已?

原文代码:https://gitee.com/felord/spring-security-oauth2-tutorial/tree/wwopen/现在很多企业都接入企业微信,作为域社群工具,企业微信开放了大量的API,可以打通很多自有应用。如果是应用,则:

本文代码: gitee.com/felord/spring-security-oauth2-tutorial/tree/wwopen/

现在很多企业都接入了企业微信,作为私域社群工具,企业微信开放了很多API,可以打通很多自有的应用。既然是应用,那肯定需要做登录。正好企业微信提供了企业微信扫码授权登录功能,而且号称使用了OAuth,正好拿这个检验一下Spring Security OAuth2专栏的威力。

正当我兴致勃勃打开文档学习的时候,脸上笑容逐渐消失,这确定是OAuth的吗?

参数都变了,跟OAuth(不管是1.0还是2.0)规定不一样,然而这还不是最离谱的。按正常OAuth2的要求,拿到code之后就可以换access_token了是吧?企业微信的access_token居然和上面扫码获取code这一步完全无关,甚至获取access_token才是第一步!

而且这个access_token接口,你还不能频繁调用,要缓存起来公用。

那费了半天劲儿去拿code有啥用呢?

居然这个code是拿用户信息的,不得不说,我服了!OAuth2的123流程被整成了213。这也就算了,命名上能不能走点心,一会儿下划线,一会儿驼峰:

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

这个JSON风格,果然是大厂,讲究!一个JSON要三个人来写才体面!反序列化的时候我还得给你写一个兼容,这是要拉满我的KPI是吧?算了,忍忍吧,老板就要这个功能,它就是一坨翔,做开发的也得含泪吃下去,干!

环境准备 准备一个内网穿透

开发微信相关的应用都需要搞一个内网穿透,在我往期的文章都有介绍。搞一个映射域名出来,就像下面这样:

invybj.natappfree.cc -> 127.0.0.1:8082

invybj.natappfree.cc会映射到我本地的8082端口,也就是我本地要开发应用的端口。

Spring Security如何与企业微信扫码登录无缝对接,其API功能让我惊叹不已?

创建应用

首先去企业微信管理后台创建一个应用,如图:

图里的参数AgentIdSecret要记下来备用。

还有一个企业微信的corpid,你可以从下面这个位置拿到,也要记下来备用。

配置内网穿透域名

创建应用这一页往下拉到页面底端,你会看到:

点击已启用进入下面这个页面:

这里配置你授权登录应用生产的正式域名或者上面内网穿透的域名,注意只配置域名,而且不能使用localhost

其实我感觉改写hosts文件也能用啊,你可以试一试。

到这里环境就搞定了,接下来就开始写Spring Security兼容代码吧。

Spring Security兼容企业微信扫码登录

写起来太恶心了,不过对比文档和OAuth2的流程之后其实也没那么麻烦。我先放出我调试好的配置:

spring: security: oauth2: client: registration: work-wechat-scan: # client-id为企业微信 的企业ID # 下面client-id是假的,你用你自己的企业ID client-id: wwaxxxxxx # client-secret企业微信对应应用的secret, # 每个企业微信应用都有独立的secret,不要搞错 # 下面client-secret假的,你用你自己创建的企业微信应用secret client-secret: nvzGI4Alp3zxxxxxxxKbnfTEets5W8 authorization-grant-type: authorization_code redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}' provider: work-wechat-scan: authorization-uri: open.work.weixin.qq.com/wwopen/sso/qrConnect token-uri: qyapi.weixin.qq.com/cgi-bin/gettoken user-info-uri: qyapi.weixin.qq.com/cgi-bin/user/getuserinfo

这里client-id使用你企业微信的企业IDclient-secret使用上面创建应用的secret值。

这里的work-wechat-scan是客户端的registrationId

封装企业微信拉起二维码URL

我们期望的是保持Spring Security OAuth2的风格,当我访问:

Converter<OAuth2AuthorizationCodeGrantRequest, RequestEntity<?>>

也就是利用OAuth2AuthorizationCodeGrantRequest生成RestTemplate需要的请求对象RequestEntity<?>。按照企业微信获取access_token的文档,这样自定义:

把这个配置到DefaultAuthorizationCodeTokenResponseClient就行了。

access_token的缓存,我放在了下一步进行解决。

适配获取用户信息

codeaccess_token都拿到了,最后一步获取用户的信息。这里是比较麻烦的因为获取access_token后并没有直接提供将code传递给OAuth2UserService的方法。最后发现OAuth2AccessTokenResponseadditionalParameters属性可以传递到OAuth2UserService,于是就利用代理模式改造了OAuth2AccessTokenResponseClient来实现:

自定义企业微信OAuth2UserService

这个和微信网页授权我封装的差不多,改下参数封装成URI交给RestTemplate请求企业微信API。恶心的是要反序列化兼容三个微信研发工程师写的一个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; } 收尾

拿到用户信息后,就结束了,你实现一个AuthenticationSuccessHandler来保证登录凭证和你平台一致,无论是cookie还是JWT,最后把它配置到这里:

invybj.natappfree.cc/login这里是内网穿透域名,出现:

企业微信扫码登录的地址其实就是invybj.natappfree.cc/oauth2/authorization/work-wechat-scan。点击跳转到扫码页面:

然后用你对应的企业微信APP扫码企业和用户要和申请应用的一致。扫码后:

这个就是Spring Security 封装的用户认证信息Authentication对象,是真正的登录,这里我没有注入权限,你需要在企业微信的OAuth2UserService实现中注入权限和更多的信息。

总结

没有实现不了的,只要把原理和流程搞清楚就行。不过如果上游微信把代码写规范一些,下游何必写这么多冗余的代码。

关注公众号:Felordcn 获取更多资讯

个人博客:felord.cn

博主:码农小胖哥
出处:felord.cn
本文版权归原作者所有,不可商用,转载需要声明出处,否则保留追究法律责任的权利。如果文中有什么错误,欢迎指出。以免更多的人被误导。
标签:扫码