refactor: 优化登录策略;简化代码

This commit is contained in:
Bunny 2025-02-18 13:40:48 +08:00
parent 27147998aa
commit 95593f6a5c
13 changed files with 142 additions and 202 deletions

View File

@ -1,20 +1,25 @@
package cn.bunny.services.security.config;
import cn.bunny.dao.entity.system.AdminUser;
import cn.bunny.dao.vo.result.ResultCodeEnum;
import cn.bunny.services.mapper.UserMapper;
import cn.bunny.services.security.custom.CustomAuthorizationManagerServiceImpl;
import cn.bunny.services.security.custom.CustomPasswordEncoder;
import cn.bunny.services.security.custom.service.CustomUserDetailsService;
import cn.bunny.services.security.custom.service.impl.CustomAuthorizationManagerServiceImpl;
import cn.bunny.services.security.filter.TokenLoginFilterService;
import cn.bunny.services.security.handelr.SecurityAccessDeniedHandler;
import cn.bunny.services.security.handelr.SecurityAuthenticationEntryPoint;
import cn.bunny.services.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.RegexRequestMatcher;
@ -24,6 +29,7 @@ import org.springframework.security.web.util.matcher.RegexRequestMatcher;
@EnableMethodSecurity
public class WebSecurityConfig {
// 需要排出的无需验证的请求路径
public static String[] annotations = {
"/", "/ws/**",
"/*/*/noAuth/**", "/*/noAuth/**", "/noAuth/**",
@ -32,10 +38,7 @@ public class WebSecurityConfig {
};
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private CustomUserDetailsService customUserDetailsService;
private UserService userService;
@Autowired
private CustomPasswordEncoder customPasswordEncoder;
@ -47,7 +50,7 @@ public class WebSecurityConfig {
private AuthenticationConfiguration authenticationConfiguration;
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
public SecurityFilterChain filterChain(HttpSecurity httpSecurity, UserMapper userMapper) throws Exception {
httpSecurity
// 前端段分离不需要---禁用明文验证
.httpBasic(AbstractHttpConfigurer::disable)
@ -73,10 +76,35 @@ public class WebSecurityConfig {
exception.accessDeniedHandler(new SecurityAccessDeniedHandler());
})
// 登录验证过滤器
.addFilterBefore(new TokenLoginFilterService(authenticationConfiguration, customUserDetailsService), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new TokenLoginFilterService(authenticationConfiguration, userService), UsernamePasswordAuthenticationFilter.class)
// 自定义密码加密器和用户登录
.passwordManagement(customPasswordEncoder).userDetailsService(customUserDetailsService);
.passwordManagement(customPasswordEncoder);
return httpSecurity.build();
}
/**
* 使用数据库方式
* 登录方式邮箱+用户名
*
* @param userMapper 获取用户数据
* @return 数据库的用户
*/
@Bean
public UserDetailsService userDetailsService(UserMapper userMapper) {
return username -> {
// 查询用户相关内容
LambdaQueryWrapper<AdminUser> queryWrapper = new LambdaQueryWrapper<AdminUser>()
.eq(AdminUser::getEmail, username)
.or()
.eq(AdminUser::getUsername, username);
// 根据邮箱查询用户名
AdminUser adminUser = userMapper.selectOne(queryWrapper);
if (adminUser == null) throw new UsernameNotFoundException(ResultCodeEnum.USER_IS_EMPTY.getMessage());
return adminUser;
};
}
}

View File

@ -13,10 +13,11 @@ import org.springframework.security.core.AuthenticationException;
@ToString
@Slf4j
public class CustomAuthenticationException extends AuthenticationException {
String message;
ResultCodeEnum resultCodeEnum;
public CustomAuthenticationException(ResultCodeEnum codeEnum) {
super(codeEnum.getMessage());
this.resultCodeEnum = codeEnum;
public CustomAuthenticationException(String message) {
super(message);
this.message = message;
}
}

View File

@ -1,4 +1,4 @@
package cn.bunny.services.security.custom.service.impl;
package cn.bunny.services.security.custom;
import cn.bunny.common.service.context.BaseContext;
import cn.bunny.common.service.utils.JwtHelper;
@ -9,7 +9,6 @@ import cn.bunny.dao.vo.result.ResultCodeEnum;
import cn.bunny.dao.vo.system.user.LoginVo;
import cn.bunny.services.mapper.PowerMapper;
import cn.bunny.services.mapper.RoleMapper;
import cn.bunny.services.security.custom.CustomAuthenticationException;
import cn.bunny.services.utils.RoleUtil;
import com.alibaba.fastjson2.JSON;
import jakarta.servlet.http.HttpServletRequest;
@ -19,6 +18,7 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;
@ -54,12 +54,12 @@ public class CustomAuthorizationManagerServiceImpl implements AuthorizationManag
// 判断是否有 token
String token = request.getHeader("token");
if (token == null) {
throw new CustomAuthenticationException(ResultCodeEnum.LOGIN_AUTH);
throw new UsernameNotFoundException(ResultCodeEnum.LOGIN_AUTH.getMessage());
}
// 判断 token 是否过期
if (JwtHelper.isExpired(token)) {
throw new CustomAuthenticationException(ResultCodeEnum.AUTHENTICATION_EXPIRED);
throw new UsernameNotFoundException(ResultCodeEnum.AUTHENTICATION_EXPIRED.getMessage());
}
// 解析JWT中的用户名
@ -72,12 +72,12 @@ public class CustomAuthorizationManagerServiceImpl implements AuthorizationManag
// 登录信息为空
if (loginVo == null) {
throw new CustomAuthenticationException(ResultCodeEnum.LOGIN_AUTH);
throw new UsernameNotFoundException(ResultCodeEnum.LOGIN_AUTH.getMessage());
}
// 判断用户是否禁用
if (loginVo.getStatus()) {
throw new CustomAuthenticationException(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED);
throw new UsernameNotFoundException(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED.getMessage());
}
// 设置用户信息

View File

@ -1,24 +0,0 @@
package cn.bunny.services.security.custom.service;
import cn.bunny.dao.dto.system.user.LoginDto;
import cn.bunny.dao.vo.system.user.LoginVo;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public interface CustomUserDetailsService extends UserDetailsService {
/**
* 根据用户名获取用户对象获取不到直接抛异常
*/
@Override
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
/**
* 前台用户登录接口
*
* @param loginDto 登录参数
* @return 登录后结果返回
*/
LoginVo login(LoginDto loginDto, HttpServletResponse response);
}

View File

@ -1,103 +0,0 @@
package cn.bunny.services.security.custom.service.impl;
import cn.bunny.common.service.exception.AuthCustomerException;
import cn.bunny.dao.dto.system.user.LoginDto;
import cn.bunny.dao.entity.system.AdminUser;
import cn.bunny.dao.enums.LoginEnums;
import cn.bunny.dao.vo.result.Result;
import cn.bunny.dao.vo.result.ResultCodeEnum;
import cn.bunny.dao.vo.system.user.LoginVo;
import cn.bunny.services.mapper.UserMapper;
import cn.bunny.services.security.custom.service.CustomUserDetailsService;
import cn.bunny.services.utils.UserUtil;
import cn.bunny.services.utils.login.DefaultLoginStrategy;
import cn.bunny.services.utils.login.EmailLoginStrategy;
import cn.bunny.services.utils.login.LoginContext;
import cn.bunny.services.utils.login.LoginStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import static cn.bunny.common.service.utils.ResponseUtil.out;
@Component
public class CustomUserDetailsServiceImpl implements CustomUserDetailsService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private UserMapper userMapper;
@Autowired
private UserUtil userUtil;
/**
* 根据用户名获取用户对象获取不到直接抛异常
*
* @param username 用户名
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 查询用户相关内容
LambdaQueryWrapper<AdminUser> queryWrapper = new LambdaQueryWrapper<AdminUser>()
.eq(AdminUser::getEmail, username)
.or()
.eq(AdminUser::getUsername, username);
// 根据邮箱查询用户名
AdminUser adminUser = userMapper.selectOne(queryWrapper);
if (adminUser == null) throw new UsernameNotFoundException(ResultCodeEnum.USER_IS_EMPTY.getMessage());
// return new CustomUser(adminUser, AuthorityUtils.createAuthorityList());
return adminUser;
}
/**
* 前台用户登录接口
*
* @param loginDto 登录参数
* @return 登录后结果返回
*/
@Override
public LoginVo login(LoginDto loginDto, HttpServletResponse response) {
String password = loginDto.getPassword();
Long readMeDay = loginDto.getReadMeDay();
// type不能为空
String type = loginDto.getType();
if (!StringUtils.hasText(type)) {
out(response, Result.error(ResultCodeEnum.REQUEST_IS_EMPTY));
return null;
}
// 初始化登录策略如果有需要添加策略放在这里
HashMap<String, LoginStrategy> loginStrategyHashMap = new HashMap<>();
loginStrategyHashMap.put(LoginEnums.EMAIL_STRATEGY.getValue(), new EmailLoginStrategy(redisTemplate, userMapper));
loginStrategyHashMap.put(LoginEnums.default_STRATEGY.getValue(), new DefaultLoginStrategy(userMapper));
// 使用登录上下文调用登录策略
LoginContext loginContext = new LoginContext(loginStrategyHashMap);
AdminUser user = loginContext.executeStrategy(type, loginDto, response);
// 判断用户是否为空
if (user == null) {
out(response, Result.error(ResultCodeEnum.LOGIN_ERROR));
return null;
}
// 对登录密码进行md5加密判断是否与数据库中一致
String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
if (!user.getPassword().equals(md5Password)) throw new AuthCustomerException(ResultCodeEnum.LOGIN_ERROR);
return userUtil.buildLoginUserVo(user, readMeDay);
}
}

View File

@ -1,14 +1,14 @@
package cn.bunny.services.security.filter;
import cn.bunny.common.service.utils.ResponseUtil;
import cn.bunny.dao.dto.system.user.LoginDto;
import cn.bunny.dao.enums.LoginEnums;
import cn.bunny.dao.vo.result.Result;
import cn.bunny.dao.vo.result.ResultCodeEnum;
import cn.bunny.dao.vo.system.user.LoginVo;
import cn.bunny.services.security.custom.service.CustomUserDetailsService;
import cn.bunny.services.security.handelr.SecurityAuthenticationFailureHandler;
import cn.bunny.services.security.handelr.SecurityAuthenticationSuccessHandler;
import cn.bunny.services.service.UserService;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.http.HttpServletRequest;
@ -18,31 +18,27 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.StringUtils;
import java.io.IOException;
import static cn.bunny.common.service.utils.ResponseUtil.out;
/**
* UsernamePasswordAuthenticationFilter
* 也可以在这里添加验证码短信等的验证
* 由于SpringSecurity的登录只能是表单形式 并且用户名密码需要时usernamepassword,可以通过继承 UsernamePasswordAuthenticationFilter 获取登录请求的参数
* 再去设置到 UsernamePasswordAuthenticationToken 来改变请求传参方式参数名等 或者也可以在登录的时候加入其他参数等等
* 自定义登录
* 自定义登录路径和自定义登录返回数据
*/
public class TokenLoginFilterService extends UsernamePasswordAuthenticationFilter {
private final CustomUserDetailsService customUserDetailsService;
private LoginDto loginDto;
private final UserService userService;
LoginDto loginDto;
public TokenLoginFilterService(AuthenticationConfiguration authenticationConfiguration, CustomUserDetailsService customUserDetailsService) throws Exception {
public TokenLoginFilterService(AuthenticationConfiguration authenticationConfiguration, UserService customUserDetailsService) throws Exception {
this.setAuthenticationSuccessHandler(new SecurityAuthenticationSuccessHandler());
this.setAuthenticationFailureHandler(new SecurityAuthenticationFailureHandler());
this.setPostOnly(false);
// 自定义登录路径自定义登录请求类型
this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(LoginEnums.LOGIN_REQUEST_API.getValue(), HttpMethod.POST.name()));
this.setAuthenticationManager(authenticationConfiguration.getAuthenticationManager());
this.customUserDetailsService = customUserDetailsService;
this.userService = customUserDetailsService;
}
/**
@ -56,28 +52,20 @@ public class TokenLoginFilterService extends UsernamePasswordAuthenticationFilte
loginDto = objectMapper.readValue(request.getInputStream(), LoginDto.class);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(loginDto.getUsername(), loginDto.getPassword());
return getAuthenticationManager().authenticate(authentication);
} catch (IOException e) {
out(response, Result.error(ResultCodeEnum.ILLEGAL_DATA_REQUEST));
return null;
} catch (Exception exception) {
throw new UsernameNotFoundException(exception.getMessage());
}
}
/**
* 验证成功
* 在这里用户的账号和密码是对的
* 此时不要再去解析/转换 request.getInputStream() 因为流已经关闭
*/
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication auth) {
// 获取登录返回信息
LoginVo loginVo = customUserDetailsService.login(loginDto, response);
if (loginVo == null) return;
// 判断用户是否禁用
if (loginVo.getStatus()) {
out(response, Result.error(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED));
return;
}
out(response, Result.success(loginVo));
LoginVo loginVo = userService.login(loginDto, response);
ResponseUtil.out(response, Result.success(loginVo));
}
/**
@ -85,12 +73,6 @@ public class TokenLoginFilterService extends UsernamePasswordAuthenticationFilte
*/
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) {
String password = loginDto.getPassword();
String username = loginDto.getUsername();
if (!StringUtils.hasText(password) || !StringUtils.hasText(username))
out(response, Result.error(ResultCodeEnum.USERNAME_OR_PASSWORD_NOT_EMPTY));
else
out(response, Result.error(null, ResultCodeEnum.LOGIN_ERROR));
ResponseUtil.out(response, Result.error(null, failed.getMessage()));
}
}

View File

@ -6,6 +6,7 @@ import cn.bunny.dao.vo.result.PageResult;
import cn.bunny.dao.vo.system.user.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.jetbrains.annotations.NotNull;
@ -20,6 +21,14 @@ import java.util.List;
* @since 2024-09-26
*/
public interface UserService extends IService<AdminUser> {
/**
* 前台用户登录接口
*
* @param loginDto 登录参数
* @return 登录后结果返回
*/
LoginVo login(LoginDto loginDto, HttpServletResponse response);
/**
* * 获取用户信息列表

View File

@ -13,6 +13,7 @@ import cn.bunny.dao.entity.system.AdminUser;
import cn.bunny.dao.entity.system.Role;
import cn.bunny.dao.entity.system.UserDept;
import cn.bunny.dao.enums.EmailTemplateEnums;
import cn.bunny.dao.enums.LoginEnums;
import cn.bunny.dao.views.ViewUserDept;
import cn.bunny.dao.vo.result.PageResult;
import cn.bunny.dao.vo.result.ResultCodeEnum;
@ -23,6 +24,10 @@ import cn.bunny.services.service.FilesService;
import cn.bunny.services.service.UserService;
import cn.bunny.services.utils.UserUtil;
import cn.bunny.services.utils.email.ConcreteSenderEmailTemplate;
import cn.bunny.services.utils.login.DefaultLoginStrategy;
import cn.bunny.services.utils.login.EmailLoginStrategy;
import cn.bunny.services.utils.login.LoginContext;
import cn.bunny.services.utils.login.LoginStrategy;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -30,12 +35,14 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
@ -84,6 +91,40 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
@Autowired
private RoleMapper roleMapper;
@Autowired
private UserMapper userMapper;
/**
* 前台用户登录接口
* 这里不用判断用户是否为空因为在登录时已经校验过了
* <p>
* 抛出异常使用自带的 UsernameNotFoundException 或者自己封装<br/>
* 但是这两个效果传入参数都是一样的所以全部使用 UsernameNotFoundException
* </p>
*
* @param loginDto 登录参数
* @return 登录后结果返回
*/
@Override
public LoginVo login(LoginDto loginDto, HttpServletResponse response) {
Long readMeDay = loginDto.getReadMeDay();
// 初始化登录策略如果有需要添加策略放在这里
HashMap<String, LoginStrategy> loginStrategyHashMap = new HashMap<>();
loginStrategyHashMap.put(LoginEnums.EMAIL_STRATEGY.getValue(), new EmailLoginStrategy(redisTemplate, userMapper));
loginStrategyHashMap.put(LoginEnums.default_STRATEGY.getValue(), new DefaultLoginStrategy(userMapper));
// 使用登录上下文调用登录策略
LoginContext loginContext = new LoginContext(loginStrategyHashMap);
AdminUser user = loginContext.executeStrategy(loginDto);
// 判断用户是否禁用
if (user.getStatus()) {
throw new UsernameNotFoundException(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED.getMessage());
}
return userUtil.buildLoginUserVo(user, readMeDay);
}
/**
* 登录发送邮件验证码
*

View File

@ -4,7 +4,6 @@ import cn.bunny.dao.dto.system.user.LoginDto;
import cn.bunny.dao.entity.system.AdminUser;
import cn.bunny.services.mapper.UserMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.servlet.http.HttpServletResponse;
/**
* 使用用户名登录
@ -18,15 +17,15 @@ public class DefaultLoginStrategy implements LoginStrategy {
/**
* 登录鉴定方法
* 默认登录方式使用用户名查询用户
*
* @param response 返回的响应
* @param loginDto 登录参数
* @return 鉴定身份验证
*/
@Override
public AdminUser authenticate(HttpServletResponse response, LoginDto loginDto) {
public AdminUser authenticate(LoginDto loginDto) {
String username = loginDto.getUsername();
String password = loginDto.getPassword();
// 查询用户相关内容
LambdaQueryWrapper<AdminUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(AdminUser::getUsername, username);

View File

@ -1,15 +1,13 @@
package cn.bunny.services.utils.login;
import cn.bunny.common.service.utils.ResponseUtil;
import cn.bunny.dao.constant.RedisUserConstant;
import cn.bunny.dao.dto.system.user.LoginDto;
import cn.bunny.dao.entity.system.AdminUser;
import cn.bunny.dao.vo.result.Result;
import cn.bunny.dao.vo.result.ResultCodeEnum;
import cn.bunny.services.mapper.UserMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
/**
* 邮箱登录策略
@ -25,26 +23,29 @@ public class EmailLoginStrategy implements LoginStrategy {
/**
* 登录鉴定方法
* 只要判断邮箱验证码是否相等在前面已经验证过用户密码
* <p>
* 抛出异常类型 UsernameNotFoundException 如果要自定义状态码需要使用 HttpServletResponse
* 有封装好的 ResponseUtil.out() 方法
* </p>
*
* @param response 返回的响应
* @param loginDto 登录参数
* @return 鉴定身份验证
*/
@Override
public AdminUser authenticate(HttpServletResponse response, LoginDto loginDto) {
public AdminUser authenticate(LoginDto loginDto) {
String username = loginDto.getUsername();
String emailCode = loginDto.getEmailCode().toLowerCase();
// 查找Redis中的验证码
Object redisEmailCode = redisTemplate.opsForValue().get(RedisUserConstant.getAdminUserEmailCodePrefix(username));
if (redisEmailCode == null) {
ResponseUtil.out(response, Result.error(ResultCodeEnum.EMAIL_CODE_EMPTY));
return null;
throw new UsernameNotFoundException(ResultCodeEnum.EMAIL_CODE_EMPTY.getMessage());
}
// 判断用户邮箱验证码是否和Redis中发送的验证码
if (!emailCode.equals(redisEmailCode.toString().toLowerCase())) {
ResponseUtil.out(response, Result.error(ResultCodeEnum.EMAIL_CODE_NOT_MATCHING));
return null;
throw new UsernameNotFoundException(ResultCodeEnum.EMAIL_CODE_NOT_MATCHING.getMessage());
}
// 查询用户相关内容

View File

@ -2,7 +2,7 @@ package cn.bunny.services.utils.login;
import cn.bunny.dao.dto.system.user.LoginDto;
import cn.bunny.dao.entity.system.AdminUser;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.util.Map;
@ -16,11 +16,19 @@ public class LoginContext {
this.strategies = strategies;
}
public AdminUser executeStrategy(String type, LoginDto loginDto, HttpServletResponse response) {
/**
* 执行登录策略
* 根据情况判断 type 是否为空
*
* @param loginDto 登录参数
* @return 用户
*/
public AdminUser executeStrategy(LoginDto loginDto) {
String type = loginDto.getType();
LoginStrategy strategy = strategies.get(type);
if (strategy == null) {
throw new IllegalArgumentException("不支持登录类型: " + type);
throw new UsernameNotFoundException("不支持登录类型: " + type);
}
return strategy.authenticate(response, loginDto);
return strategy.authenticate(loginDto);
}
}

View File

@ -2,7 +2,6 @@ package cn.bunny.services.utils.login;
import cn.bunny.dao.dto.system.user.LoginDto;
import cn.bunny.dao.entity.system.AdminUser;
import jakarta.servlet.http.HttpServletResponse;
/**
* 登录策略
@ -12,9 +11,8 @@ public interface LoginStrategy {
/**
* 登录鉴定方法
*
* @param response 返回的响应
* @param loginDto 登录参数
* @return 鉴定身份验证
*/
AdminUser authenticate(HttpServletResponse response, LoginDto loginDto);
AdminUser authenticate(LoginDto loginDto);
}

View File

@ -89,7 +89,7 @@ management:
web:
exposure:
include: "*"
base-path: /admin/actuator
base-path: /api/actuator
info:
env:
enabled: true