refactor: 优化安全配置和代码结构
This commit is contained in:
parent
bb9a0d7213
commit
d2bb69798a
@ -26,31 +26,38 @@ public interface CacheKey {
|
||||
* 用户
|
||||
*/
|
||||
String USER_ID = "user::id:";
|
||||
|
||||
/**
|
||||
* 数据
|
||||
*/
|
||||
String DATA_USER = "data::user:";
|
||||
|
||||
/**
|
||||
* 菜单
|
||||
*/
|
||||
String MENU_ID = "menu::id:";
|
||||
String MENU_USER = "menu::user:";
|
||||
|
||||
/**
|
||||
* 角色授权
|
||||
*/
|
||||
String ROLE_AUTH = "role::auth:";
|
||||
|
||||
/**
|
||||
* 角色信息
|
||||
*/
|
||||
String ROLE_ID = "role::id:";
|
||||
|
||||
/**
|
||||
* 部门
|
||||
*/
|
||||
String DEPT_ID = "dept::id:";
|
||||
|
||||
/**
|
||||
* 岗位
|
||||
*/
|
||||
String JOB_ID = "job::id:";
|
||||
|
||||
/**
|
||||
* 数据字典
|
||||
*/
|
||||
|
@ -13,13 +13,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.security.config.bean;
|
||||
package me.zhengjie.modules.security.config;
|
||||
|
||||
import com.wf.captcha.*;
|
||||
import com.wf.captcha.base.Captcha;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import me.zhengjie.exception.BadRequestException;
|
||||
import me.zhengjie.modules.security.config.enums.LoginCodeEnum;
|
||||
import me.zhengjie.utils.StringUtils;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -33,7 +34,7 @@ import java.awt.*;
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "login.code")
|
||||
public class CodeProperties {
|
||||
public class CaptchaConfig {
|
||||
|
||||
/**
|
||||
* 验证码配置
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2020 the original author or authors.
|
||||
*
|
||||
* 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 me.zhengjie.modules.security.config;
|
||||
|
||||
import me.zhengjie.modules.security.config.bean.LoginProperties;
|
||||
import me.zhengjie.modules.security.config.bean.SecurityProperties;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @apiNote 配置文件转换Pojo类的 统一配置 类
|
||||
* @author: liaojinlong
|
||||
* @date: 2020/6/10 19:04
|
||||
*/
|
||||
@Configuration
|
||||
public class ConfigBeanConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConfigurationProperties(prefix = "login")
|
||||
public LoginProperties loginProperties() {
|
||||
return new LoginProperties();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConfigurationProperties(prefix = "jwt")
|
||||
public SecurityProperties securityProperties() {
|
||||
return new SecurityProperties();
|
||||
}
|
||||
}
|
@ -13,9 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.security.config.bean;
|
||||
package me.zhengjie.modules.security.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 配置文件读取
|
||||
@ -24,6 +26,8 @@ import lombok.Data;
|
||||
* @date loginCode.length0loginCode.length0/6/10 17:loginCode.length6
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "login")
|
||||
public class LoginProperties {
|
||||
|
||||
/**
|
||||
@ -31,5 +35,5 @@ public class LoginProperties {
|
||||
*/
|
||||
private boolean singleLogin = false;
|
||||
|
||||
public static final String cacheKey = "user-login-cache:";
|
||||
public static final String cacheKey = "user_login_cache:";
|
||||
}
|
@ -13,9 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.security.config.bean;
|
||||
package me.zhengjie.modules.security.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Jwt参数配置
|
||||
@ -24,6 +26,8 @@ import lombok.Data;
|
||||
* @date 2019年11月28日
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "jwt")
|
||||
public class SecurityProperties {
|
||||
|
||||
/**
|
@ -16,7 +16,6 @@
|
||||
package me.zhengjie.modules.security.config;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.zhengjie.modules.security.config.bean.SecurityProperties;
|
||||
import me.zhengjie.modules.security.security.*;
|
||||
import me.zhengjie.modules.security.service.OnlineUserService;
|
||||
import me.zhengjie.modules.security.service.UserCacheManager;
|
||||
|
@ -13,13 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.security.config.bean;
|
||||
package me.zhengjie.modules.security.config.enums;
|
||||
|
||||
/**
|
||||
* 验证码配置枚举
|
||||
*
|
||||
* @author: liaojinlong
|
||||
* @date: 2020/6/10 17:40
|
||||
* @author liaojinlong
|
||||
* @date 2020/6/10 17:40
|
||||
*/
|
||||
|
||||
public enum LoginCodeEnum {
|
||||
@ -39,5 +39,8 @@ public enum LoginCodeEnum {
|
||||
* 闪图
|
||||
*/
|
||||
GIF,
|
||||
/**
|
||||
* 静态
|
||||
*/
|
||||
SPEC
|
||||
}
|
@ -27,10 +27,10 @@ import me.zhengjie.annotation.rest.AnonymousGetMapping;
|
||||
import me.zhengjie.annotation.rest.AnonymousPostMapping;
|
||||
import me.zhengjie.config.properties.RsaProperties;
|
||||
import me.zhengjie.exception.BadRequestException;
|
||||
import me.zhengjie.modules.security.config.bean.CodeProperties;
|
||||
import me.zhengjie.modules.security.config.bean.LoginCodeEnum;
|
||||
import me.zhengjie.modules.security.config.bean.LoginProperties;
|
||||
import me.zhengjie.modules.security.config.bean.SecurityProperties;
|
||||
import me.zhengjie.modules.security.config.CaptchaConfig;
|
||||
import me.zhengjie.modules.security.config.enums.LoginCodeEnum;
|
||||
import me.zhengjie.modules.security.config.LoginProperties;
|
||||
import me.zhengjie.modules.security.config.SecurityProperties;
|
||||
import me.zhengjie.modules.security.security.TokenProvider;
|
||||
import me.zhengjie.modules.security.service.dto.AuthUserDto;
|
||||
import me.zhengjie.modules.security.service.dto.JwtUserDto;
|
||||
@ -70,7 +70,7 @@ public class AuthController {
|
||||
private final OnlineUserService onlineUserService;
|
||||
private final TokenProvider tokenProvider;
|
||||
private final AuthenticationManagerBuilder authenticationManagerBuilder;
|
||||
private final CodeProperties codeProperties;
|
||||
private final CaptchaConfig captchaConfig;
|
||||
private final LoginProperties loginProperties;
|
||||
|
||||
@Log("用户登录")
|
||||
@ -124,7 +124,7 @@ public class AuthController {
|
||||
@AnonymousGetMapping(value = "/code")
|
||||
public ResponseEntity<Object> getCode() {
|
||||
// 获取运算的结果
|
||||
Captcha captcha = codeProperties.getCaptcha();
|
||||
Captcha captcha = captchaConfig.getCaptcha();
|
||||
String uuid = properties.getCodeKey() + IdUtil.simpleUUID();
|
||||
//当验证码类型为 arithmetic时且长度 >= 2 时,captcha.text()的结果有几率为浮点型
|
||||
String captchaValue = captcha.text();
|
||||
@ -132,7 +132,7 @@ public class AuthController {
|
||||
captchaValue = captchaValue.split("\\.")[0];
|
||||
}
|
||||
// 保存
|
||||
redisUtils.set(uuid, captchaValue, codeProperties.getExpiration(), TimeUnit.MINUTES);
|
||||
redisUtils.set(uuid, captchaValue, captchaConfig.getExpiration(), TimeUnit.MINUTES);
|
||||
// 验证码信息
|
||||
Map<String, Object> imgResult = new HashMap<String, Object>(2) {{
|
||||
put("img", captcha.toBase64());
|
||||
|
@ -15,10 +15,12 @@
|
||||
*/
|
||||
package me.zhengjie.modules.security.security;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import me.zhengjie.exception.handler.ApiError;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
@ -32,6 +34,10 @@ public class JwtAccessDeniedHandler implements AccessDeniedHandler {
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
|
||||
//当用户在没有授权的情况下访问受保护的REST资源时,将调用此方法发送403 Forbidden响应
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage());
|
||||
response.setStatus(HttpStatus.FORBIDDEN.value());
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
String jsonResponse = objectMapper.writeValueAsString(ApiError.error(HttpStatus.FORBIDDEN.value(), "禁止访问,您没有权限访问此资源"));
|
||||
response.getWriter().write(jsonResponse);
|
||||
}
|
||||
}
|
||||
|
@ -15,10 +15,13 @@
|
||||
*/
|
||||
package me.zhengjie.modules.security.security;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.zhengjie.exception.handler.ApiError;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
@ -26,14 +29,18 @@ import java.io.IOException;
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||
|
||||
@Override
|
||||
public void commence(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
AuthenticationException authException) throws IOException {
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
|
||||
// 当用户尝试访问安全的REST资源而不提供任何凭据时,将调用此方法发送401 响应
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException==null?"Unauthorized":authException.getMessage());
|
||||
int code = HttpStatus.UNAUTHORIZED.value();
|
||||
response.setStatus(code);
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
String jsonResponse = objectMapper.writeValueAsString(ApiError.error(HttpStatus.UNAUTHORIZED.value(), "登录状态已过期,请重新登录"));
|
||||
response.getWriter().write(jsonResponse);
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
package me.zhengjie.modules.security.security;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.zhengjie.modules.security.config.bean.SecurityProperties;
|
||||
import me.zhengjie.modules.security.config.SecurityProperties;
|
||||
import me.zhengjie.modules.security.service.OnlineUserService;
|
||||
import me.zhengjie.modules.security.service.UserCacheManager;
|
||||
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
|
||||
|
@ -17,7 +17,7 @@ package me.zhengjie.modules.security.security;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import io.jsonwebtoken.ExpiredJwtException;
|
||||
import me.zhengjie.modules.security.config.bean.SecurityProperties;
|
||||
import me.zhengjie.modules.security.config.SecurityProperties;
|
||||
import me.zhengjie.modules.security.service.UserCacheManager;
|
||||
import me.zhengjie.modules.security.service.dto.OnlineUserDto;
|
||||
import me.zhengjie.modules.security.service.OnlineUserService;
|
||||
|
@ -23,7 +23,7 @@ import io.jsonwebtoken.*;
|
||||
import io.jsonwebtoken.io.Decoders;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.zhengjie.modules.security.config.bean.SecurityProperties;
|
||||
import me.zhengjie.modules.security.config.SecurityProperties;
|
||||
import me.zhengjie.utils.RedisUtils;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
|
@ -19,12 +19,11 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.zhengjie.modules.security.security.TokenProvider;
|
||||
import me.zhengjie.utils.PageResult;
|
||||
import me.zhengjie.modules.security.config.bean.SecurityProperties;
|
||||
import me.zhengjie.modules.security.config.SecurityProperties;
|
||||
import me.zhengjie.modules.security.service.dto.JwtUserDto;
|
||||
import me.zhengjie.modules.security.service.dto.OnlineUserDto;
|
||||
import me.zhengjie.utils.*;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
@ -16,7 +16,7 @@
|
||||
package me.zhengjie.modules.security.service;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import me.zhengjie.modules.security.config.bean.LoginProperties;
|
||||
import me.zhengjie.modules.security.config.LoginProperties;
|
||||
import me.zhengjie.modules.security.service.dto.JwtUserDto;
|
||||
import me.zhengjie.utils.RedisUtils;
|
||||
import me.zhengjie.utils.StringUtils;
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2019-2020 the original author or authors.
|
||||
*
|
||||
* 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 me.zhengjie.sysrunner;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
* @description 程序启动后处理数据
|
||||
* @date 2025-01-13
|
||||
**/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class SystemRunner implements ApplicationRunner {
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) {
|
||||
}
|
||||
}
|
@ -86,9 +86,9 @@ jwt:
|
||||
# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
|
||||
token-validity-in-seconds: 14400000
|
||||
# 在线用户key
|
||||
online-key: "online-token:"
|
||||
online-key: "online_token:"
|
||||
# 验证码
|
||||
code-key: "captcha-code:"
|
||||
code-key: "captcha_code:"
|
||||
# token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
|
||||
detect: 1800000
|
||||
# 续期时间范围,默认1小时,单位毫秒
|
||||
|
@ -90,9 +90,9 @@ jwt:
|
||||
# 令牌过期时间 此处单位/毫秒 ,默认2小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
|
||||
token-validity-in-seconds: 7200000
|
||||
# 在线用户key
|
||||
online-key: "online-token:"
|
||||
online-key: "online_token:"
|
||||
# 验证码
|
||||
code-key: "captcha-code:"
|
||||
code-key: "captcha_code:"
|
||||
# token 续期检查时间范围(默认30分钟,单位默认毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期
|
||||
detect: 1800000
|
||||
# 续期时间范围,默认 1小时,这里单位毫秒
|
||||
|
Loading…
Reference in New Issue
Block a user