mirror of
https://github.com/continew-org/continew-admin.git
synced 2025-09-08 12:57:13 +08:00
Merge branch 'jskils-fix-last-commit' into dev
This commit is contained in:
@@ -99,10 +99,24 @@ public class LoginUser implements Serializable {
|
||||
*/
|
||||
private LocalDateTime loginTime;
|
||||
|
||||
public LoginUser(Set<String> permissions, Set<String> roleCodes, Set<RoleDTO> roles) {
|
||||
/**
|
||||
* 最后一次修改密码时间
|
||||
*/
|
||||
private LocalDateTime pwdResetTime;
|
||||
|
||||
/**
|
||||
* 登录时系统设置的密码过期天数
|
||||
*/
|
||||
private Integer passwordExpirationDays;
|
||||
|
||||
public LoginUser(Set<String> permissions,
|
||||
Set<String> roleCodes,
|
||||
Set<RoleDTO> roles,
|
||||
Integer passwordExpirationDays) {
|
||||
this.permissions = permissions;
|
||||
this.roleCodes = roleCodes;
|
||||
this.roles = roles;
|
||||
this.passwordExpirationDays = passwordExpirationDays;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,4 +130,21 @@ public class LoginUser implements Serializable {
|
||||
}
|
||||
return roleCodes.contains(SysConstants.ADMIN_ROLE_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 密码是否已过期
|
||||
*
|
||||
* @return 是否过期
|
||||
*/
|
||||
public boolean isPasswordExpired() {
|
||||
// 永久有效
|
||||
if (this.passwordExpirationDays == null || this.passwordExpirationDays <= SysConstants.NO) {
|
||||
return false;
|
||||
}
|
||||
// 初始密码(第三方登录用户)暂不提示修改
|
||||
if (this.pwdResetTime == null) {
|
||||
return false;
|
||||
}
|
||||
return this.pwdResetTime.plusDays(this.passwordExpirationDays).isBefore(LocalDateTime.now());
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.admin.auth.config.satoken;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 密码配置属性
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2024/6/15 22:15
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "auth.password")
|
||||
public class LoginPasswordProperties {
|
||||
|
||||
/**
|
||||
* 排除(放行)路径配置
|
||||
*/
|
||||
private String[] excludes = new String[0];
|
||||
}
|
@@ -16,9 +16,17 @@
|
||||
|
||||
package top.continew.admin.auth.config.satoken;
|
||||
|
||||
import cn.dev33.satoken.interceptor.SaInterceptor;
|
||||
import cn.dev33.satoken.router.SaRouter;
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import top.continew.admin.common.model.dto.LoginUser;
|
||||
import top.continew.admin.common.util.helper.LoginHelper;
|
||||
import top.continew.starter.auth.satoken.autoconfigure.SaTokenExtensionProperties;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
import top.continew.starter.core.util.validate.CheckUtils;
|
||||
|
||||
/**
|
||||
* Sa-Token 配置
|
||||
@@ -27,8 +35,12 @@ import org.springframework.context.annotation.Configuration;
|
||||
* @since 2022/12/19 22:13
|
||||
*/
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class SaTokenConfiguration {
|
||||
|
||||
private final SaTokenExtensionProperties properties;
|
||||
private final LoginPasswordProperties loginPasswordProperties;
|
||||
|
||||
/**
|
||||
* Sa-Token 权限认证配置
|
||||
*/
|
||||
@@ -36,4 +48,20 @@ public class SaTokenConfiguration {
|
||||
public StpInterface stpInterface() {
|
||||
return new SaTokenPermissionImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* SaToken 拦截器配置
|
||||
*/
|
||||
@Bean
|
||||
public SaInterceptor saInterceptor() {
|
||||
return new SaInterceptor(handle -> SaRouter.match(StringConstants.PATH_PATTERN)
|
||||
.notMatch(properties.getSecurity().getExcludes())
|
||||
.check(r -> {
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
if (SaRouter.isMatchCurrURI(loginPasswordProperties.getExcludes())) {
|
||||
return;
|
||||
}
|
||||
CheckUtils.throwIf(loginUser.isPasswordExpired(), "密码已过期,请修改密码");
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@@ -68,6 +68,8 @@ import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static top.continew.admin.system.enums.PasswordPolicyEnum.PASSWORD_EXPIRATION_DAYS;
|
||||
|
||||
/**
|
||||
* 登录业务实现
|
||||
*
|
||||
@@ -209,8 +211,11 @@ public class LoginServiceImpl implements LoginService {
|
||||
.listRoleCodeByUserId(userId), threadPoolTaskExecutor);
|
||||
CompletableFuture<Set<RoleDTO>> roleFuture = CompletableFuture.supplyAsync(() -> roleService
|
||||
.listByUserId(userId), threadPoolTaskExecutor);
|
||||
CompletableFuture<Integer> passwordExpirationDaysFuture = CompletableFuture.supplyAsync(() -> optionService
|
||||
.getValueByCode2Int(PASSWORD_EXPIRATION_DAYS.name()));
|
||||
CompletableFuture.allOf(permissionFuture, roleCodeFuture, roleFuture);
|
||||
LoginUser loginUser = new LoginUser(permissionFuture.join(), roleCodeFuture.join(), roleFuture.join());
|
||||
LoginUser loginUser = new LoginUser(permissionFuture.join(), roleCodeFuture.join(), roleFuture
|
||||
.join(), passwordExpirationDaysFuture.join());
|
||||
BeanUtil.copyProperties(user, loginUser);
|
||||
return LoginHelper.login(loginUser);
|
||||
}
|
||||
|
@@ -29,7 +29,6 @@ import top.continew.starter.data.mybatis.plus.service.IService;
|
||||
import top.continew.starter.extension.crud.service.BaseService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -90,14 +89,6 @@ public interface UserService extends BaseService<UserResp, UserDetailResp, UserQ
|
||||
*/
|
||||
void updatePassword(String oldPassword, String newPassword, Long id);
|
||||
|
||||
/**
|
||||
* 密码是否已过期
|
||||
*
|
||||
* @param pwdResetTime 上次重置密码时间
|
||||
* @return 是否过期
|
||||
*/
|
||||
boolean isPasswordExpired(LocalDateTime pwdResetTime);
|
||||
|
||||
/**
|
||||
* 修改手机号
|
||||
*
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
package top.continew.admin.system.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.img.ImgUtil;
|
||||
@@ -210,20 +211,8 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserRes
|
||||
baseMapper.updateById(user);
|
||||
// 保存历史密码
|
||||
userPasswordHistoryService.add(id, password, passwordRepetitionTimes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPasswordExpired(LocalDateTime pwdResetTime) {
|
||||
// 永久有效
|
||||
int passwordExpirationDays = optionService.getValueByCode2Int(PASSWORD_EXPIRATION_DAYS.name());
|
||||
if (passwordExpirationDays <= SysConstants.NO) {
|
||||
return false;
|
||||
}
|
||||
// 初始密码也提示修改
|
||||
if (pwdResetTime == null) {
|
||||
return true;
|
||||
}
|
||||
return pwdResetTime.plusDays(passwordExpirationDays).isBefore(LocalDateTime.now());
|
||||
// 修改后登出
|
||||
StpUtil.logout();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -128,7 +128,7 @@ public class AuthController {
|
||||
UserInfoResp userInfoResp = BeanUtil.copyProperties(userDetailResp, UserInfoResp.class);
|
||||
userInfoResp.setPermissions(loginUser.getPermissions());
|
||||
userInfoResp.setRoles(loginUser.getRoleCodes());
|
||||
userInfoResp.setPwdExpired(userService.isPasswordExpired(userDetailResp.getPwdResetTime()));
|
||||
userInfoResp.setPwdExpired(loginUser.isPasswordExpired());
|
||||
return R.ok(userInfoResp);
|
||||
}
|
||||
|
||||
|
@@ -190,6 +190,16 @@ cosid:
|
||||
machine-bit: 3
|
||||
sequence-bit: 9
|
||||
|
||||
--- ### 认证配置
|
||||
auth:
|
||||
## 密码配置
|
||||
password:
|
||||
excludes:
|
||||
- /auth/route
|
||||
- /auth/user/info
|
||||
- /auth/logout
|
||||
- /system/user/password
|
||||
|
||||
--- ### 服务器配置
|
||||
server:
|
||||
servlet:
|
||||
|
Reference in New Issue
Block a user