refactor: 优化安全配置和修改登录逻辑隐藏密码信息

This commit is contained in:
Jie Zheng 2025-01-14 10:32:12 +08:00
parent eff0fd9e12
commit 1b5b265d02
5 changed files with 29 additions and 23 deletions

View File

@ -33,7 +33,6 @@ import org.springframework.security.config.core.GrantedAuthorityDefaults;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.filter.CorsFilter; import org.springframework.web.filter.CorsFilter;
import java.util.*; import java.util.*;
@ -74,7 +73,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
httpSecurity httpSecurity
// 禁用 CSRF // 禁用 CSRF
.csrf().disable() .csrf().disable()
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class) .addFilter(corsFilter)
// 授权异常 // 授权异常
.exceptionHandling() .exceptionHandling()
.authenticationEntryPoint(authenticationErrorHandler) .authenticationEntryPoint(authenticationErrorHandler)

View File

@ -32,6 +32,7 @@ import me.zhengjie.modules.security.config.enums.LoginCodeEnum;
import me.zhengjie.modules.security.config.LoginProperties; import me.zhengjie.modules.security.config.LoginProperties;
import me.zhengjie.modules.security.config.SecurityProperties; import me.zhengjie.modules.security.config.SecurityProperties;
import me.zhengjie.modules.security.security.TokenProvider; import me.zhengjie.modules.security.security.TokenProvider;
import me.zhengjie.modules.security.service.UserDetailsServiceImpl;
import me.zhengjie.modules.security.service.dto.AuthUserDto; import me.zhengjie.modules.security.service.dto.AuthUserDto;
import me.zhengjie.modules.security.service.dto.JwtUserDto; import me.zhengjie.modules.security.service.dto.JwtUserDto;
import me.zhengjie.modules.security.service.OnlineUserService; import me.zhengjie.modules.security.service.OnlineUserService;
@ -42,13 +43,12 @@ import me.zhengjie.utils.StringUtils;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -65,13 +65,15 @@ import java.util.concurrent.TimeUnit;
@RequiredArgsConstructor @RequiredArgsConstructor
@Api(tags = "系统:系统授权接口") @Api(tags = "系统:系统授权接口")
public class AuthController { public class AuthController {
private final SecurityProperties properties; private final SecurityProperties properties;
private final RedisUtils redisUtils; private final RedisUtils redisUtils;
private final OnlineUserService onlineUserService; private final OnlineUserService onlineUserService;
private final TokenProvider tokenProvider; private final TokenProvider tokenProvider;
private final AuthenticationManagerBuilder authenticationManagerBuilder;
private final CaptchaConfig captchaConfig; private final CaptchaConfig captchaConfig;
private final LoginProperties loginProperties; private final LoginProperties loginProperties;
private final PasswordEncoder passwordEncoder;
private final UserDetailsServiceImpl userDetailsService;
@Log("用户登录") @Log("用户登录")
@ApiOperation("登录授权") @ApiOperation("登录授权")
@ -89,27 +91,29 @@ public class AuthController {
if (StringUtils.isBlank(authUser.getCode()) || !authUser.getCode().equalsIgnoreCase(code)) { if (StringUtils.isBlank(authUser.getCode()) || !authUser.getCode().equalsIgnoreCase(code)) {
throw new BadRequestException("验证码错误"); throw new BadRequestException("验证码错误");
} }
UsernamePasswordAuthenticationToken authenticationToken = // 获取用户信息
new UsernamePasswordAuthenticationToken(authUser.getUsername(), password); JwtUserDto jwtUser = userDetailsService.loadUserByUsername(authUser.getUsername());
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken); // 验证用户密码
if (!passwordEncoder.matches(password, jwtUser.getPassword())) {
throw new BadRequestException("登录密码错误");
}
Authentication authentication = new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication); SecurityContextHolder.getContext().setAuthentication(authentication);
// 生成令牌与第三方系统获取令牌方式 // 生成令牌
// UserDetails userDetails = userDetailsService.loadUserByUsername(userInfo.getUsername());
// Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
// SecurityContextHolder.getContext().setAuthentication(authentication);
String token = tokenProvider.createToken(authentication); String token = tokenProvider.createToken(authentication);
final JwtUserDto jwtUserDto = (JwtUserDto) authentication.getPrincipal(); // 将密码设置为空
jwtUser.setPassword(null);
// 返回 token 用户信息 // 返回 token 用户信息
Map<String, Object> authInfo = new HashMap<String, Object>(2) {{ Map<String, Object> authInfo = new HashMap<String, Object>(2) {{
put("token", properties.getTokenStartWith() + token); put("token", properties.getTokenStartWith() + token);
put("user", jwtUserDto); put("user", jwtUser);
}}; }};
if (loginProperties.isSingleLogin()) { if (loginProperties.isSingleLogin()) {
// 踢掉之前已经登录的token // 踢掉之前已经登录的token
onlineUserService.kickOutForUsername(authUser.getUsername()); onlineUserService.kickOutForUsername(authUser.getUsername());
} }
// 保存在线信息 // 保存在线信息
onlineUserService.save(jwtUserDto, token, request); onlineUserService.save(jwtUser, token, request);
// 返回登录信息 // 返回登录信息
return ResponseEntity.ok(authInfo); return ResponseEntity.ok(authInfo);
} }
@ -117,7 +121,10 @@ public class AuthController {
@ApiOperation("获取用户信息") @ApiOperation("获取用户信息")
@GetMapping(value = "/info") @GetMapping(value = "/info")
public ResponseEntity<UserDetails> getUserInfo() { public ResponseEntity<UserDetails> getUserInfo() {
return ResponseEntity.ok(SecurityUtils.getCurrentUser()); JwtUserDto jwtUser = (JwtUserDto) SecurityUtils.getCurrentUser();
// 将密码设置为空
jwtUser.setPassword(null);
return ResponseEntity.ok(jwtUser);
} }
@ApiOperation("获取验证码") @ApiOperation("获取验证码")

View File

@ -50,7 +50,7 @@ public class UserDetailsServiceImpl implements UserDetailsService {
if (!user.getEnabled()) { if (!user.getEnabled()) {
throw new BadRequestException("账号未激活!"); throw new BadRequestException("账号未激活!");
} }
jwtUserDto = new JwtUserDto(user, dataService.getDeptIds(user), roleService.buildAuthorities(user)); jwtUserDto = new JwtUserDto(user, dataService.getDeptIds(user), roleService.buildAuthorities(user), user.getPassword());
// 添加缓存数据 // 添加缓存数据
userCacheManager.addUserCache(username, jwtUserDto); userCacheManager.addUserCache(username, jwtUserDto);
} }

View File

@ -18,6 +18,7 @@ package me.zhengjie.modules.security.service.dto;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import me.zhengjie.modules.system.domain.User; import me.zhengjie.modules.system.domain.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import java.util.List; import java.util.List;
@ -38,16 +39,13 @@ public class JwtUserDto implements UserDetails {
private final List<AuthorityDto> authorities; private final List<AuthorityDto> authorities;
@Setter
private String password;
public Set<String> getRoles() { public Set<String> getRoles() {
return authorities.stream().map(AuthorityDto::getAuthority).collect(Collectors.toSet()); return authorities.stream().map(AuthorityDto::getAuthority).collect(Collectors.toSet());
} }
@Override
@JSONField(serialize = false)
public String getPassword() {
return user.getPassword();
}
@Override @Override
@JSONField(serialize = false) @JSONField(serialize = false)
public String getUsername() { public String getUsername() {

View File

@ -15,6 +15,7 @@
*/ */
package me.zhengjie.modules.system.domain; package me.zhengjie.modules.system.domain;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
@ -87,6 +88,7 @@ public class User extends BaseEntity implements Serializable {
@ApiModelProperty(value = "头像存储的路径", hidden = true) @ApiModelProperty(value = "头像存储的路径", hidden = true)
private String avatarPath; private String avatarPath;
@JSONField(serialize = false)
@ApiModelProperty(value = "密码") @ApiModelProperty(value = "密码")
private String password; private String password;