mirror of
https://github.com/dataease/dataease.git
synced 2026-05-24 06:18:10 +08:00
feat: 完善token续命刷新机制
This commit is contained in:
@@ -5,9 +5,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@EnableCaching
|
||||
@SpringBootApplication(exclude = {
|
||||
QuartzAutoConfiguration.class,
|
||||
LdapAutoConfiguration.class
|
||||
|
||||
@@ -14,7 +14,7 @@ public interface AuthApi {
|
||||
|
||||
|
||||
@PostMapping("/login")
|
||||
Object login(LoginDto loginDto);
|
||||
Object login(LoginDto loginDto) throws Exception;
|
||||
|
||||
|
||||
@PostMapping("/userInfo")
|
||||
@@ -23,6 +23,9 @@ public interface AuthApi {
|
||||
@GetMapping("/isLogin")
|
||||
Boolean isLogin();
|
||||
|
||||
@PostMapping("/logout")
|
||||
String logout();
|
||||
|
||||
|
||||
@GetMapping("/test")
|
||||
String test();
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.dataease.auth.config;
|
||||
|
||||
import io.dataease.auth.entity.JWTToken;
|
||||
import io.dataease.auth.entity.SysUserEntity;
|
||||
import io.dataease.auth.entity.TokenInfo;
|
||||
import io.dataease.auth.service.AuthUserService;
|
||||
import io.dataease.auth.util.JWTUtils;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
@@ -34,9 +35,8 @@ public class F2CRealm extends AuthorizingRealm {
|
||||
//验证资源权限
|
||||
@Override
|
||||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
||||
String username = JWTUtils.getUsername(principals.toString());
|
||||
SysUserEntity user = authUserService.getUser(username);
|
||||
Long userId = user.getUserId();
|
||||
Long userId = JWTUtils.tokenInfoByToken(principals.toString()).getUserId();
|
||||
//SysUserEntity user = authUserService.getUserById(userId);
|
||||
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
|
||||
Set<String> role = authUserService.roles(userId).stream().collect(Collectors.toSet());
|
||||
simpleAuthorizationInfo.addRoles(role);
|
||||
@@ -50,12 +50,14 @@ public class F2CRealm extends AuthorizingRealm {
|
||||
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
|
||||
String token = (String) auth.getCredentials();
|
||||
// 解密获得username,用于和数据库进行对比
|
||||
String username = JWTUtils.getUsername(token);
|
||||
TokenInfo tokenInfo = JWTUtils.tokenInfoByToken(token);
|
||||
Long userId = tokenInfo.getUserId();
|
||||
String username = tokenInfo.getUsername();
|
||||
if (username == null) {
|
||||
throw new AuthenticationException("token invalid");
|
||||
}
|
||||
|
||||
SysUserEntity user = authUserService.getUser(username);
|
||||
SysUserEntity user = authUserService.getUserById(userId);
|
||||
if (user == null) {
|
||||
throw new AuthenticationException("User didn't existed!");
|
||||
}
|
||||
@@ -66,7 +68,7 @@ public class F2CRealm extends AuthorizingRealm {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (! JWTUtils.verify(token, username, pass)) {
|
||||
if (! JWTUtils.verify(token, tokenInfo, pass)) {
|
||||
throw new AuthenticationException("Username or password error");
|
||||
}
|
||||
return new SimpleAuthenticationInfo(token, token, "f2cReam");
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.dataease.auth.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Data
|
||||
@Component
|
||||
public class RsaProperties {
|
||||
|
||||
public static String privateKey;
|
||||
|
||||
@Value("${rsa.private_key}")
|
||||
public void setPrivateKey(String privateKey) {
|
||||
RsaProperties.privateKey = privateKey;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ public class ShiroConfig {
|
||||
|
||||
|
||||
|
||||
|
||||
@Bean("securityManager")
|
||||
public DefaultWebSecurityManager getManager(F2CRealm f2cRealm) {
|
||||
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
|
||||
@@ -49,6 +50,7 @@ public class ShiroConfig {
|
||||
filterMap.put("f2cPerms", new F2CPermissionsFilter());
|
||||
//filterMap.put("f2cRoles", new F2CRolesFilter());
|
||||
filterMap.put("jwt", new JWTFilter());
|
||||
/*filterMap.put("jwt", jwtFilter);*/
|
||||
filterMap.put("logout", new F2CLogoutFilter());
|
||||
factoryBean.setSecurityManager(securityManager);
|
||||
factoryBean.setUnauthorizedUrl("/permissionMiss");
|
||||
|
||||
21
backend/src/main/java/io/dataease/auth/entity/TokenInfo.java
Normal file
21
backend/src/main/java/io/dataease/auth/entity/TokenInfo.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package io.dataease.auth.entity;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class TokenInfo implements Serializable {
|
||||
|
||||
private String username;
|
||||
|
||||
private Long userId;
|
||||
|
||||
private Long lastLoginTime;
|
||||
|
||||
public String format(){
|
||||
return username + "," +userId;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,31 @@
|
||||
package io.dataease.auth.filter;
|
||||
|
||||
import io.dataease.auth.entity.JWTToken;
|
||||
import io.dataease.auth.entity.SysUserEntity;
|
||||
import io.dataease.auth.entity.TokenInfo;
|
||||
import io.dataease.auth.service.AuthUserService;
|
||||
import io.dataease.auth.util.JWTUtils;
|
||||
import io.dataease.commons.utils.CommonBeanFactory;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public class JWTFilter extends BasicHttpAuthenticationFilter {
|
||||
|
||||
|
||||
private Logger LOGGER = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/*@Autowired
|
||||
private AuthUserService authUserService;*/
|
||||
|
||||
|
||||
/**
|
||||
* 判断用户是否想要登入。
|
||||
@@ -67,25 +73,22 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
|
||||
return false;
|
||||
}
|
||||
|
||||
private String refreshToken(ServletRequest request, ServletResponse response) {
|
||||
private String refreshToken(ServletRequest request, ServletResponse response) throws Exception{
|
||||
// 获取AccessToken(Shiro中getAuthzHeader方法已经实现)
|
||||
String token = this.getAuthzHeader(request);
|
||||
// 获取当前Token的帐号信息
|
||||
String username = JWTUtils.getUsername(token);
|
||||
String password = "123456";
|
||||
try {
|
||||
String newToken = JWTUtils.sign(username, password);
|
||||
JWTToken jwtToken = new JWTToken(newToken);
|
||||
this.getSubject(request, response).login(jwtToken);
|
||||
// 设置响应的Header头新Token
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
||||
httpServletResponse.addHeader("Access-Control-Expose-Headers", "Authorization");
|
||||
httpServletResponse.setHeader("Authorization", newToken);
|
||||
return newToken;
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
TokenInfo tokenInfo = JWTUtils.tokenInfoByToken(token);
|
||||
AuthUserService authUserService = CommonBeanFactory.getBean(AuthUserService.class);
|
||||
SysUserEntity user = authUserService.getUserById(tokenInfo.getUserId());
|
||||
String password = user.getPassword();
|
||||
String newToken = JWTUtils.sign(tokenInfo, password);
|
||||
JWTToken jwtToken = new JWTToken(newToken);
|
||||
this.getSubject(request, response).login(jwtToken);
|
||||
// 设置响应的Header头新Token
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
||||
httpServletResponse.addHeader("Access-Control-Expose-Headers", "RefreshAuthorization");
|
||||
httpServletResponse.setHeader("RefreshAuthorization", newToken);
|
||||
return newToken;
|
||||
}
|
||||
|
||||
|
||||
@@ -113,8 +116,10 @@ public class JWTFilter extends BasicHttpAuthenticationFilter {
|
||||
private void response401(ServletRequest req, ServletResponse resp) {
|
||||
try {
|
||||
HttpServletResponse httpServletResponse = (HttpServletResponse) resp;
|
||||
httpServletResponse.sendRedirect("/401");
|
||||
} catch (IOException e) {
|
||||
httpServletResponse.addHeader("Access-Control-Expose-Headers", "authentication-status");
|
||||
httpServletResponse.setHeader("authentication-status", "invalid");
|
||||
httpServletResponse.setStatus(401);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,18 @@ import io.dataease.auth.api.AuthApi;
|
||||
import io.dataease.auth.api.dto.CurrentRoleDto;
|
||||
import io.dataease.auth.api.dto.CurrentUserDto;
|
||||
import io.dataease.auth.api.dto.LoginDto;
|
||||
import io.dataease.auth.config.RsaProperties;
|
||||
import io.dataease.auth.entity.SysUserEntity;
|
||||
import io.dataease.auth.entity.TokenInfo;
|
||||
import io.dataease.auth.service.AuthUserService;
|
||||
import io.dataease.auth.util.JWTUtils;
|
||||
import io.dataease.auth.util.RsaUtil;
|
||||
import io.dataease.commons.utils.BeanUtils;
|
||||
import io.dataease.commons.utils.CodingUtil;
|
||||
import io.dataease.commons.utils.ServletUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import java.util.HashMap;
|
||||
@@ -26,36 +30,35 @@ public class AuthServer implements AuthApi {
|
||||
|
||||
|
||||
@Override
|
||||
public Object login(@RequestBody LoginDto loginDto) {
|
||||
public Object login(@RequestBody LoginDto loginDto) throws Exception {
|
||||
String username = loginDto.getUsername();
|
||||
String password = loginDto.getPassword();
|
||||
SysUserEntity user = authUserService.getUser(username);
|
||||
SysUserEntity user = authUserService.getUserByName(username);
|
||||
String realPwd = user.getPassword();
|
||||
if (StringUtils.isEmpty(realPwd)){
|
||||
if (ObjectUtils.isEmpty(user)){
|
||||
throw new RuntimeException("没有该用户!");
|
||||
}
|
||||
/*String pwd = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, password);
|
||||
String realPass = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, realPwd);
|
||||
if (!StrUtil.equals(pwd, realPass)){
|
||||
throw new RuntimeException("密码错误!");
|
||||
}*/
|
||||
if (!StringUtils.equals(realPwd, password)){
|
||||
//私钥解密
|
||||
String pwd = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, password);
|
||||
//md5加密
|
||||
pwd = CodingUtil.md5(pwd);
|
||||
|
||||
if (!StringUtils.equals(pwd, realPwd)){
|
||||
throw new RuntimeException("密码错误!");
|
||||
}
|
||||
/*Map<String,Object> result = new HashMap<>();
|
||||
result.put("token", JWTUtils.sign(username, realPwd));*/
|
||||
String token = JWTUtils.sign(username, realPwd);
|
||||
ServletUtils.setToken(token);
|
||||
Map<String,Object> result = new HashMap<>();
|
||||
TokenInfo tokenInfo = TokenInfo.builder().userId(user.getUserId()).username(username).lastLoginTime(System.currentTimeMillis()).build();
|
||||
String token = JWTUtils.sign(tokenInfo, realPwd);
|
||||
result.put("token", token);
|
||||
ServletUtils.setToken(token);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CurrentUserDto userInfo() {
|
||||
String token = ServletUtils.getToken();
|
||||
String username = JWTUtils.getUsername(token);
|
||||
SysUserEntity user = authUserService.getUser(username);
|
||||
Long userId = JWTUtils.tokenInfoByToken(token).getUserId();
|
||||
SysUserEntity user = authUserService.getUserById(userId);
|
||||
CurrentUserDto currentUserDto = BeanUtils.copyBean(new CurrentUserDto(), user);
|
||||
List<CurrentRoleDto> currentRoleDtos = authUserService.roleInfos(user.getUserId());
|
||||
List<String> permissions = authUserService.permissions(user.getUserId());
|
||||
@@ -64,7 +67,7 @@ public class AuthServer implements AuthApi {
|
||||
return currentUserDto;
|
||||
}
|
||||
|
||||
@PostMapping("/logout")
|
||||
@Override
|
||||
public String logout(){
|
||||
return "success";
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ public interface AuthUserService {
|
||||
|
||||
|
||||
|
||||
SysUserEntity getUser(String username);
|
||||
SysUserEntity getUserById(Long userId);
|
||||
|
||||
SysUserEntity getUserByName(String username);
|
||||
|
||||
List<String> roles(Long userId);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.dataease.auth.entity.SysUserEntity;
|
||||
import io.dataease.base.mapper.ext.AuthMapper;
|
||||
import io.dataease.auth.service.AuthUserService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@@ -15,14 +16,27 @@ import java.util.stream.Collectors;
|
||||
@Service
|
||||
public class AuthUserServiceImpl implements AuthUserService {
|
||||
|
||||
private final String USER_CACHE_NAME = "users_info";
|
||||
|
||||
@Resource
|
||||
private AuthMapper authMapper;
|
||||
|
||||
/**
|
||||
* 此处需被F2CRealm登录认证调用 也就是说每次请求都会被调用 所以最好加上缓存
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@Cacheable(value = USER_CACHE_NAME, key = "'user' + #userId" )
|
||||
@Override
|
||||
public SysUserEntity getUserById(Long userId){
|
||||
return authMapper.findUser(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysUserEntity getUser(String username){
|
||||
return authMapper.findUser(username);
|
||||
public SysUserEntity getUserByName(String username) {
|
||||
return authMapper.findUserByName(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> roles(Long userId){
|
||||
return authMapper.roleCodes(userId);
|
||||
|
||||
@@ -30,10 +30,14 @@ public class ShiroServiceImpl implements ShiroService {
|
||||
filterChainDefinitionMap.put("/v3/**","anon");
|
||||
filterChainDefinitionMap.put("/static/**", "anon");
|
||||
|
||||
|
||||
// filterChainDefinitionMap.put("/401", "anon");
|
||||
// filterChainDefinitionMap.put("/404", "anon");
|
||||
// 登陆
|
||||
// filterChainDefinitionMap.put("/api/auth/logout", "anon");
|
||||
filterChainDefinitionMap.put("/api/auth/login", "anon");
|
||||
// 退出
|
||||
//filterChainDefinitionMap.put("/logout", "anon");
|
||||
|
||||
// 放行未授权接口,重定向使用
|
||||
filterChainDefinitionMap.put("/unauth", "anon");
|
||||
filterChainDefinitionMap.put("/display/**", "anon");
|
||||
@@ -43,7 +47,6 @@ public class ShiroServiceImpl implements ShiroService {
|
||||
// 被挤下线
|
||||
filterChainDefinitionMap.put("/downline", "anon");
|
||||
// 放行 end ----------------------------------------------------------
|
||||
filterChainDefinitionMap.put("/logout", "logout");
|
||||
|
||||
/*List<ExtPermissionBean> extPermissionBeans = extUserMapper.getPermissions();
|
||||
|
||||
@@ -53,7 +56,7 @@ public class ShiroServiceImpl implements ShiroService {
|
||||
filterChainDefinitionMap.put(item.getPath(), "jwt," + f2cPerms);
|
||||
});
|
||||
*/
|
||||
|
||||
filterChainDefinitionMap.put("/api/auth/logout", "logout");
|
||||
filterChainDefinitionMap.put("/**", "jwt");
|
||||
return filterChainDefinitionMap;
|
||||
}
|
||||
|
||||
@@ -5,15 +5,19 @@ import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import io.dataease.auth.entity.TokenInfo;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class JWTUtils {
|
||||
|
||||
|
||||
// 过期时间5分钟
|
||||
private static final long EXPIRE_TIME = 5*60*1000;
|
||||
|
||||
// token过期时间5分钟 (过期会自动刷新续命 目的是避免一直都是同一个token )
|
||||
private static final long EXPIRE_TIME = 1*60*1000;
|
||||
// 登录间隔时间 超过这个时间强制重新登录
|
||||
private static final long Login_Interval = 2*60*1000;
|
||||
|
||||
|
||||
/**
|
||||
@@ -22,10 +26,12 @@ public class JWTUtils {
|
||||
* @param secret 用户的密码
|
||||
* @return 是否正确
|
||||
*/
|
||||
public static boolean verify(String token, String username, String secret) {
|
||||
public static boolean verify(String token, TokenInfo tokenInfo, String secret) {
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
JWTVerifier verifier = JWT.require(algorithm)
|
||||
.withClaim("username", username)
|
||||
.withClaim("lastLoginTime", tokenInfo.getLastLoginTime())
|
||||
.withClaim("username", tokenInfo.getUsername())
|
||||
.withClaim("userId", tokenInfo.getUserId())
|
||||
.build();
|
||||
verifier.verify(token);
|
||||
return true;
|
||||
@@ -35,18 +41,22 @@ public class JWTUtils {
|
||||
* 获得token中的信息无需secret解密也能获得
|
||||
* @return token中包含的用户名
|
||||
*/
|
||||
public static String getUsername(String token) {
|
||||
try {
|
||||
DecodedJWT jwt = JWT.decode(token);
|
||||
return jwt.getClaim("username").asString();
|
||||
} catch (JWTDecodeException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
public static TokenInfo tokenInfoByToken(String token) {
|
||||
DecodedJWT jwt = JWT.decode(token);
|
||||
String username = jwt.getClaim("username").asString();
|
||||
Long userId = jwt.getClaim("userId").asLong();
|
||||
Long lastLoginTime = jwt.getClaim("lastLoginTime").asLong();
|
||||
if (StringUtils.isEmpty(username) || ObjectUtils.isEmpty(userId) || ObjectUtils.isEmpty(lastLoginTime)){
|
||||
throw new RuntimeException("token格式错误!");
|
||||
}
|
||||
TokenInfo tokenInfo = TokenInfo.builder().username(username).userId(userId).lastLoginTime(lastLoginTime).build();
|
||||
return tokenInfo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static boolean needRefresh(String token){
|
||||
Date exp = JWTUtils.getExp(token);
|
||||
return new Date().getTime() >= exp.getTime();
|
||||
@@ -64,17 +74,19 @@ public class JWTUtils {
|
||||
|
||||
/**
|
||||
* 生成签名,5min后过期
|
||||
* @param username 用户名
|
||||
* @param tokenInfo 用户信息
|
||||
* @param secret 用户的密码
|
||||
* @return 加密的token
|
||||
*/
|
||||
public static String sign(String username, String secret) {
|
||||
public static String sign(TokenInfo tokenInfo, String secret) {
|
||||
try {
|
||||
Date date = new Date(System.currentTimeMillis()+EXPIRE_TIME);
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
// 附带username信息
|
||||
return JWT.create()
|
||||
.withClaim("username", username)
|
||||
.withClaim("lastLoginTime", tokenInfo.getLastLoginTime())
|
||||
.withClaim("username", tokenInfo.getUsername())
|
||||
.withClaim("userId", tokenInfo.getUserId())
|
||||
.withClaim("exp", date)
|
||||
.withExpiresAt(date)
|
||||
.sign(algorithm);
|
||||
|
||||
29
backend/src/main/java/io/dataease/auth/util/RsaUtil.java
Normal file
29
backend/src/main/java/io/dataease/auth/util/RsaUtil.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package io.dataease.auth.util;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
|
||||
public class RsaUtil {
|
||||
|
||||
/**
|
||||
* 私钥解密
|
||||
*
|
||||
* @param privateKeyText 私钥
|
||||
* @param text 待解密的文本
|
||||
* @return /
|
||||
* @throws Exception /
|
||||
*/
|
||||
public static String decryptByPrivateKey(String privateKeyText, String text) throws Exception {
|
||||
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText));
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
|
||||
return new String(result);
|
||||
}
|
||||
}
|
||||
@@ -15,11 +15,12 @@ public interface AuthMapper {
|
||||
List<String> roleCodes(@Param("userId") Long userId);
|
||||
|
||||
|
||||
|
||||
List<String> permissions(@Param("userId") Long userId);
|
||||
|
||||
|
||||
SysUserEntity findUser(@Param("username") String username);
|
||||
SysUserEntity findUser(@Param("userId") Long userId);
|
||||
|
||||
SysUserEntity findUserByName(@Param("username") String username);
|
||||
|
||||
|
||||
List<CurrentRoleDto> roles(@Param("userId") Long userId);
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
|
||||
|
||||
<select id="findUser" resultMap="baseMap">
|
||||
select user_id, username,nick_name, dept_id, password, enabled,email, phone from sys_user where user_id = #{userId}
|
||||
</select>
|
||||
|
||||
<select id="findUserByName" resultMap="baseMap">
|
||||
select user_id, username,nick_name, dept_id, password, enabled,email, phone from sys_user where username = #{username}
|
||||
</select>
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.dataease.commons.utils;
|
||||
|
||||
import io.dataease.auth.entity.TokenInfo;
|
||||
import io.dataease.auth.util.JWTUtils;
|
||||
import io.dataease.base.domain.SysUser;
|
||||
import io.dataease.service.sys.SysUserService;
|
||||
@@ -18,9 +19,9 @@ public class AuthUtils {
|
||||
|
||||
public static SysUser getUser(){
|
||||
String token = ServletUtils.getToken();
|
||||
String username = JWTUtils.getUsername(token);
|
||||
TokenInfo tokenInfo = JWTUtils.tokenInfoByToken(token);
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setUsername(username);
|
||||
sysUser.setUserId(tokenInfo.getUserId());
|
||||
SysUser user = sysUserService.findOne(sysUser);
|
||||
return user;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.github.pagehelper.PageHelper;
|
||||
import io.dataease.commons.utils.PageUtils;
|
||||
import io.dataease.commons.utils.Pager;
|
||||
import io.dataease.controller.sys.request.SysUserCreateRequest;
|
||||
import io.dataease.controller.sys.request.SysUserPwdRequest;
|
||||
import io.dataease.controller.sys.request.SysUserStateRequest;
|
||||
import io.dataease.controller.sys.request.UserGridRequest;
|
||||
import io.dataease.controller.sys.response.SysUserGridResponse;
|
||||
@@ -55,4 +56,11 @@ public class SysUserController {
|
||||
public void updateStatus(@RequestBody SysUserStateRequest request){
|
||||
sysUserService.updateStatus(request);
|
||||
}
|
||||
|
||||
@ApiOperation("更新用户密码")
|
||||
@PostMapping("/updatePwd")
|
||||
public void updatePwd(@RequestBody SysUserPwdRequest request){
|
||||
|
||||
sysUserService.updatePwd(request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.dataease.controller.sys.request;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class SysUserPwdRequest implements Serializable {
|
||||
|
||||
private Long userId;
|
||||
private String password;
|
||||
private String repeatPassword;
|
||||
private String newPassword;
|
||||
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import io.dataease.base.mapper.ext.ExtSysUserMapper;
|
||||
import io.dataease.commons.utils.BeanUtils;
|
||||
import io.dataease.commons.utils.CodingUtil;
|
||||
import io.dataease.controller.sys.request.SysUserCreateRequest;
|
||||
import io.dataease.controller.sys.request.SysUserPwdRequest;
|
||||
import io.dataease.controller.sys.request.SysUserStateRequest;
|
||||
import io.dataease.controller.sys.request.UserGridRequest;
|
||||
import io.dataease.controller.sys.response.SysUserGridResponse;
|
||||
@@ -17,6 +18,7 @@ import io.dataease.controller.sys.response.SysUserRole;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import javax.annotation.Resource;
|
||||
@@ -26,6 +28,7 @@ import java.util.stream.Collectors;
|
||||
@Service
|
||||
public class SysUserService {
|
||||
|
||||
private final static String USER_CACHE_NAME = "users_info";
|
||||
private final static String DEFAULT_PWD = "DataEase123..";
|
||||
|
||||
@Resource
|
||||
@@ -83,6 +86,33 @@ public class SysUserService {
|
||||
return sysUserMapper.updateByPrimaryKeySelective(sysUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户密码清楚缓存
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@CacheEvict(value = USER_CACHE_NAME, key = "'user' + #request.userId")
|
||||
public int updatePwd(SysUserPwdRequest request) {
|
||||
if (!StringUtils.equals(request.getPassword(), request.getRepeatPassword())){
|
||||
throw new RuntimeException("两次密码不一致");
|
||||
}
|
||||
SysUser temp = new SysUser();
|
||||
temp.setUserId(request.getUserId());
|
||||
SysUser user = findOne(temp);
|
||||
if (ObjectUtils.isEmpty(user)) {
|
||||
throw new RuntimeException("用户不存在");
|
||||
}
|
||||
if (!StringUtils.equals(request.getPassword(), user.getPassword())){
|
||||
throw new RuntimeException("密码错误");
|
||||
}
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setUserId(request.getUserId());
|
||||
sysUser.setPassword(CodingUtil.md5(request.getNewPassword()));
|
||||
return sysUserMapper.updateByPrimaryKeySelective(sysUser);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 删除用户角色关联
|
||||
* @param userId
|
||||
@@ -108,6 +138,7 @@ public class SysUserService {
|
||||
});
|
||||
}
|
||||
|
||||
@CacheEvict(value = USER_CACHE_NAME, key = "'user' + #userId")
|
||||
@Transactional
|
||||
public int delete(Long userId){
|
||||
deleteUserRoles(userId);
|
||||
|
||||
Reference in New Issue
Block a user