网上很多都是基于是spring原有认证,无法实现小程序认证,于是乎改写了部分代码。当然,也可以添加手机验证码登陆,有兴趣的可以参照现有代码来实现。
基于springboot的oauth2 jwt,使用私钥进行加密,token信息保存在redis中。用户密码加密方式SCryptPasswordEncoder。
源码:https://github.com/aLiang-xyl/oauth2
springboot的oauth2相关知识可参见:https://docs.spring.io/spring-security/site/docs/current/reference/html5/#preface
私钥
用于oauth2认证服务
keytool -genkey -alias auth-jwt -keypass 123456 -keyalg RSA -storetype PKCS12 -keysize 1024 -validity 365 -keystore auth-jwt.jks -storepass 123456 -dname "CN=(Felord), OU=(auth-jwt), O=(auth-jwt), L=(zz), ST=(hn), C=(cn)"
公钥
基于私钥生成公钥,用于oauth2资源服务进行验签
使用下面的命令,将公钥信息保存在任意文本中,例如:public.pub
keytool -list -rfc --keystore auth-jwt.jks | openssl x509 -inform pem -pubkey
oauth:
#token有效期24小时
access-token-validity-seconds: 86400
#refresh token有效期48小时
refresh-token-validity-seconds: 172800
client:
#普通用户
common:
clinet-id: oauth-client-id
client-secret: oauth-client-secret
#微信小程序用户
weixin:
clinet-id: wx-oauth-client-id
client-secret: wx-oauth-client-secret
#微信登陆配置
weixin:
small-program:
#小程序登陆接口
auth-url: https://api.weixin.qq.com/sns/jscode2session?grant_type=authorization_code&appid=${oauth.weixin.small-program.appid}&secret=${oauth.weixin.small-program.secret}&js_code=
appid:
secret:
#下面的请求路径会跳过权限校验
path-matchers:
permit-all: '/test**, /test/**, /free/**, /static/**, /register**, /health, /info, /hystrix.stream/**, /trace, /features, /dump, /webjars/**, /swagger-ui.html, /swagger-resources/**, /**/v2/api-docs, /v2/api-docs, /favicon.ico, /actuator/**'
jks:
#私钥配置
path: certs/auth-jwt.jks
#私钥密码
password: 123456
#alias
key-pair-alias: auth-jwt
微信小程序登陆接口调用和普通登陆类似,需要将js_code作为用户名参数,不需要password参数,后台将调用微信小程序接口查询openid,根据openid查询用户信息,如果用户不存在则新增一个小程序用户
http://localhost:8080/oauth/token?client_id=wx-oauth-client-id&client_secret=wx-oauth-client-secret&grant_type=password&username=12345678
因个人公共组件库未开源,没有添加相关功能,望见谅
表结构可参见SysUser类
OAuth2官方文档
+--------+ +---------------+
| |--(A)------- Authorization Grant --------->| |
| | | |
| |<-(B)----------- Access Token -------------| |
| | & Refresh Token | |
| | | |
| | +----------+ | |
| |--(C)---- Access Token ---->| | | |
| | | | | |
| |<-(D)- Protected Resource --| Resource | | Authorization |
| Client | | Server | | Server |
| |--(E)---- Access Token ---->| | | |
| | | | | |
| |<-(F)- Invalid Token Error -| | | |
| | +----------+ | |
| | | |
| |--(G)----------- Refresh Token ----------->| |
| | | |
| |<-(H)----------- Access Token -------------| |
+--------+ & Optional Refresh Token +---------------+
Figure: Refreshing an Expired Access Token
图所示的流程包括以下步骤:
(A)客户端通过向客户端进行身份验证来请求访问令牌
授权服务器并显示授权授权。
(B)授权服务器对客户端进行身份验证并验证
授权授予,如果有效,则颁发访问令牌
和刷新令牌。
(C)客户端向资源发出受保护的资源请求
通过显示访问令牌来访问服务器。
(D)资源服务器验证访问令牌,如果有效,
服务请求。
(E)重复步骤(C)和(D),直到访问令牌过期。如果
客户端知道访问令牌已过期,则跳至步骤(G);
否则,它将发出另一个受保护的资源请求。
(F)由于访问令牌无效,因此资源服务器返回
无效的令牌错误。
(G)客户端通过与进行身份验证来请求新的访问令牌
授权服务器并显示刷新令牌。的
客户端身份验证要求基于客户端类型
和授权服务器策略上。
(H)授权服务器对客户端进行身份验证并验证
刷新令牌,如果有效,则发出新的访问令牌(并且,
(可选)新的刷新令牌)。