当前位置:网站首页>Oauth2.0 认证服务器添加验证码登陆方式
Oauth2.0 认证服务器添加验证码登陆方式
2022-08-02 14:14:00 【zhangyu丶】
发送验证码
@RestController
@AllArgsConstructor
@RequestMapping
public class LoginController {
private final RedisTemplate<String, String> redisTemplate;
@GetMapping(value = "captcha/{phone}")
public R captcha(@PathVariable String phone) {
String captcha = randomCode();
redisTemplate.opsForValue().set(phone, captcha, 600, TimeUnit.SECONDS);
return R.ok(captcha);
}
private static String randomCode() {
Random random = new Random();
int code = random.nextInt(10000);
DecimalFormat format = new DecimalFormat("0000");
return format.format(code);
}
}
登陆验证码校验过滤器 CaptchaFilter
@Slf4j
@Component
@RequiredArgsConstructor
public class CaptchaFilter extends OncePerRequestFilter {
private final RedisTemplate<String, String> redisTemplate;
private final UserService userService;
private RequestMatcher requestMatcher = new AntPathRequestMatcher("/oauth/token", HttpMethod.POST.name());
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (requestMatcher.matches(request)) {
String grantType = request.getParameter("grant_type");
if (StrUtil.equalsIgnoreCase(grantType, "captcha")) {
try {
verifyCaptcha(request);
} catch (BusinessException e) {
log.error("登陆验证码校验异常: {}, {}", e.getCode(), e.getMsg());
R.failRender(e.getCode(), e.getMsg(), response, HttpStatus.INTERNAL_SERVER_ERROR.value());
return;
}
}
}
filterChain.doFilter(request, response);
}
private void verifyCaptcha(HttpServletRequest request) throws ServletRequestBindingException {
String phone = ServletRequestUtils.getStringParameter(request, "username");
String captcha = ServletRequestUtils.getStringParameter(request, "password");
String cache = redisTemplate.opsForValue().get(phone);
if (Objects.isNull(cache) || !captcha.equals(cache)) {
throw new BusinessException("验证码校验异常");
}
}
}
自定义一种授权模式 CaptchaTokenGranter
- 自定义验证码授权模式
- 配置到 AuthorizationServerConfig.tokenGranter()
- 将配置好的授权列表添加到 AuthorizationServerEndpointsConfigurer 中
public class CaptchaTokenGranter extends AbstractTokenGranter {
private static final String GRANT_TYPE = "captcha";
private UserDetailsServiceImpl userDetailsServiceImpl;
public CaptchaTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, UserDetailsServiceImpl userDetailsServiceImpl) {
super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
this.userDetailsServiceImpl = userDetailsServiceImpl;
}
@Override
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
Map<String, String> requestParameters = tokenRequest.getRequestParameters();
String username = requestParameters.getOrDefault("username", "");
UserDetails userDetails = userDetailsServiceImpl.loadUserByUsername(username);
if (Objects.isNull(userDetails)) {
throw new UsernameNotFoundException("Username Not Found Exception");
}
// 构建用户授权信息
Authentication user = new UsernamePasswordAuthenticationToken(userDetails.getUsername(),
userDetails.getPassword(), userDetails.getAuthorities());
return new OAuth2Authentication(tokenRequest.createOAuth2Request(client), user);
}
}
将定义的授权模式添加到认证服务器核心配置 AuthorizationServerConfig 的端点配置中
AuthorizationServerConfig 其他配置已省略,详细见 Oauth2.0 认证服务器搭建
@Configuration
@EnableAuthorizationServer
@AllArgsConstructor
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
......
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenGranter(tokenGranter(endpoints)); //配置授权方式
}
/** * 先获取已有的五种授权列表,然后将自定义的授权方式置入 * * @param endpoints AuthorizationServerEndpointsConfigurer * @return TokenGranter */
private TokenGranter tokenGranter(final AuthorizationServerEndpointsConfigurer endpoints) {
List<TokenGranter> granters = new ArrayList<>(Collections.singletonList(endpoints.getTokenGranter()));
granters.add(new CaptchaTokenGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(),
endpoints.getOAuth2RequestFactory(), userDetailsServiceImpl));
return new CompositeTokenGranter(granters);
}
......
}
Oauth2.0 系列文章
以下是同步到语雀的、可读性好一点,CSDN 继续看的点专栏就好。
Oauth2.0 核心篇
Oauth2.0 安全性(以微信授权登陆为例)
Oauth2.0 认证服务器搭建
Oauth2.0 添加验证码登陆方式
Oauth2.0 资源服务器搭建
Oauth2.0 自定义响应值以及异常处理
Oauth2.0 补充
边栏推荐
猜你喜欢
1. Development community homepage, register
锥形相位掩模的Talbot图像
【线程】 理解线程(并行)线程同步的处理(信号量,互斥锁,读写锁,条件变量)
change the available bandwidth of tcp flow dynamically in mininet
第三十一章:二叉树的概念与性质
使用1D-1D EPE的光波导布局设计工具
tcp transparent proxy (IP_TRANSPARENT)
Unity-PlayMaker
unity-shader(中级)
Exotic curiosity-a solution looking - bit operations
随机推荐
Windows下mysql服务无法启动:服务没有报告任何错误。
audio console无法连接到RPC服务
线性结构,顺序结构
Codeforces Round #605 (Div. 3)
mininet multihomed topology
图解MESI(缓存一致性协议)
饥荒联机版Mod开发——准备工具(一)
Detailed explanation of MATLAB drawing function fplot
光学好书推荐
双链表(普通迭代器和常性迭代器)
Qt | 播放音频文件 QMediaplayer
系统性能和TCP/UDP网络优化-学习大杂烩
分布式一致性协议-Gossip
嵌入式学习硬件篇------初识ARM
mininet hosts talk to real internet
Unity Line-Renderer
Unity插件-FairyGUI
【线程网络】了解线程属性(fork/interview question)
Detailed explanation of MATLAB drawing function plot
C语言函数调用过程-汇编分析