共计 3951 个字符,预计需要花费 10 分钟才能阅读完成。
最近实现了一个多端登录的 Spring Security 组件,用起来十分丝滑,开箱即用,可插拔,而且灵活性十分强。我感觉能满足大部分场景的须要。目前实现了手机号验证码和微信小程序两种自定义登录,加上默认的 Form 登录,一共三种,当初开源分享给大家,接下来简略介绍一下这个插件包。
DSL 配置格调
切入正题,先来看看配置:
@Bean
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {http.csrf().disable()
.authorizeRequests()
.mvcMatchers("/foo/**")
.access("hasAuthority('ROLE_USER')").anyRequest().authenticated()
.and()
// 默认 form 表单登录
.formLogin()
.and()
.apply(new LoginFilterSecurityConfigurer<>())
// 验证码登录
.captchaLogin(captchaLoginConfigurer ->
// 验证码校验 1 在此处配置 优先级最高 2 注册为 Spring Bean 能够免配置
captchaLoginConfigurer.captchaService(this::verifyCaptchaMock)
// 依据手机号查问用户 UserDetials 1 在此处配置 优先级最高 2 注册为 Spring Bean 能够免配置
.captchaUserDetailsService(this::loadUserByPhoneMock)
// 生成 JWT 返回 1 在此处配置 优先级最高 2 注册为 Spring Bean 能够免配置
.jwtTokenGenerator(this::tokenResponseMock)
//todo 其它配置省略……
)
// 小程序登录 同时反对多个小程序
.miniAppLogin(miniAppLoginConfigurer -> miniAppLoginConfigurer
// 实现小程序多租户
// 依据申请携带的 clientid 查问小程序的 appid 和 secret 1 在此处配置 优先级最高 2 注册为 Spring Bean 能够免配置
.miniAppClientService(this::miniAppClientMock)
// 小程序用户 主动注册和检索 1 在此处配置 优先级最高 2 注册为 Spring Bean 能够免配置
.miniAppUserDetailsService(new MiniAppUserDetailsServiceMock())
// 小程序 sessionkey 缓存 过期工夫应该小于微信官网文档的申明 1 在此处配置 优先级最高 2 注册为 Spring Bean 能够免配置
.miniAppSessionKeyCache(new MiniAppSessionKeyCacheMock())
// 生成 JWT 返回 1 在此处配置 优先级最高 2 注册为 Spring Bean 能够免配置
.jwtTokenGenerator(this::tokenResponseMock)
//todo 其它配置省略……
);
return http.build();}
这种格调齐全贴合了 Spring Security 的DSL配置格调,不仅仅高大上,而且能够按需配置。如果你没有验证码登录间接删掉 captchaLogin
办法;如果你没有微信小程序登录间接删掉 miniAppLogin
办法。甚至还能够对单种登录进行细粒度定制化,formLogin
有的性能根本验证码登录和微信小程序登录的都有。
为什么这么灵便?
这里形象了一个登录配置类:
public abstract class AbstractLoginFilterConfigurer<H extends HttpSecurityBuilder<H>,
C extends AbstractLoginFilterConfigurer<H, C, F>,
F extends AbstractAuthenticationProcessingFilter>
extends AbstractHttpConfigurer<AbstractLoginFilterConfigurer<H, C, F>, H> {// 省略……}
所有额定的登录渠道大都能够通过这个类来扩大,负责验证码登录的 CaptchaLoginFilterConfigurer
和微信小程序登录的 MiniAppLoginFilterConfigurer
都是该类实现的,基本上你看了源码也能照葫芦画瓢来一个。
另外下面这些配置项接口,都能够放在 Spring IoC 中,配置类能主动获取,不过优先级最高的还是通过下面代码中配置的具体实现,原理参见上面的的样例:
@Override
protected AuthenticationSuccessHandler defaultSuccessHandler(H http) {
// 如果配置类没有配置 就尝试去 Spring IoC 中发现
if (this.jwtTokenGenerator == null) {ApplicationContext applicationContext = http.getSharedObject(ApplicationContext.class);
jwtTokenGenerator = getBeanOrNull(applicationContext, JwtTokenGenerator.class);
}
Assert.notNull(jwtTokenGenerator, "jwtTokenGenerator is required");
return new LoginAuthenticationSuccessHandler(jwtTokenGenerator);
}
public final <T> T getBeanOrNull(ApplicationContext applicationContext, Class<T> beanType) {String[] beanNames = applicationContext.getBeanNamesForType(beanType);
if (beanNames.length == 1) {return applicationContext.getBean(beanNames[0], beanType);
}
return null;
}
应用办法
自行应用 Maven 命令 mvn install
到本地仓库,而后引入:
<dependency>
<groupId>cn.felord</groupId>
<artifactId>spring-security-extension</artifactId>
<version>1.0.0</version>
</dependency>
而后参考样例 sample 我的项目进行开发,登录形式有三种。
一般登录
原生 Spring Security 接口
POST /login?username=user&password=12345 HTTP/1.1
Host: localhost:8080
验证码登录
须要先实现必须的配置接口
发送验证码后调用验证码登录接口:
POST /login/captcha?phone=11111111111&captcha=123123 HTTP/1.1
Host: localhost:8080
小程序登录
须要先实现必须的配置接口
前端先调用微信受权登录接口获取openid
:
POST /miniapp/preauth?clientId=wxxda23234&jsCode=051A23234ZHa1tZ5yj3AOlFr HTTP/1.1
Host: localhost:8080
响应:
{
"code": 200,
"data": {
"errcode": null,
"errmsg": null,
"sessionKey": null,
"openid": "oWmZj5QBrZxxxxx8OUxRrZJi4",
"unionid": "oS-dxxxxxx4w_x7dA-h9MIuA"
},
"msg": "","identifier": true
}
而后调用小程序登录接口:
POST /login/miniapp HTTP/1.1
Host: localhost:8080
Content-Type: application/json
{
"clientId": "wxd14qr6",
"openId": "oWmZj5QBrZIBks0xx8OUxRrZJi4",
"unionId": "oS-dK520tgW8xxxx7dA-h9MIuA",
"iv":"LQUOt8BSTa7xxxpe1Q==",
"encryptedData": "10hn3o4xxxxxrO/Ag5nRD3QkLSzduKnWuzN9B/H4Y0G5mDPR8siA7T8yaaqZsrMycLAoe2qrd1J75yYetYuWifiq3jUrcceRZHVxxl9LnQdW8f5+pMTnQtCYiMJ7Jm9paCw2Bh+5Lowkyqkx1q0fALvCQ9LXPPLAbLOB9CavRfKoenAmyyHQjZ/6lz0njzA=="
}
获取形式
Gitee: felord/spring-security-login-extension
关注公众号:Felordcn 获取更多资讯
集体博客:https://felord.cn