一、config源码
package org.example.common.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* springboot 跨域配置类
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 设置允许跨域的路径
registry.addMapping("/**")
// 设置允许跨域请求的域名
.allowedOriginPatterns("*")
// 是否允许cookie
.allowCredentials(true)
// 设置允许的请求方式
.allowedMethods("GET", "POST", "DELETE", "PUT")
// 设置允许的header属性
.allowedHeaders("*")
// 跨域允许时间
.maxAge(3600);
}
}
package org.example.common.config;
import org.example.common.util.FastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* redis配置类
* 避免存入redis中的key看上去乱码的现象
*/
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings(value = {"unchecked", "rawtypes"})
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
// Hash的key也采用StringRedisSerializer的序列化方式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
}
package org.example.common.config;
import org.example.common.security.AccessDeniedHandlerImpl;
import org.example.common.security.AuthenticationEntryPointImpl;
import org.example.common.security.JwtAuthenticationTokenFilter;
import org.example.common.security.LoginUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.MessageDigestPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* SpringSecurity 核心配置类
* prePostEnabled = true 开启注解权限认证功能
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)//开启@PreAuthorize()注解权限功能
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final static Logger logger = LoggerFactory.getLogger(LoginUser.class);
//认证过滤器
@Autowired
private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
// 认证失败处理器
@Autowired
private AuthenticationEntryPointImpl authenticationEntryPoint;
// 授权失败处理器
@Autowired
private AccessDeniedHandlerImpl accessDeniedHandler;
/**
* 密码机密处理器
* <p>
* 将BCryptPasswordEncoder对象注入到spring容器中,更换掉原来的 PasswordEncoder加密方式
* 原PasswordEncoder密码格式为:{id}password。它会根据id去判断密码的加密方式。
* 如果没替换原来的加密方式,数据库中想用明文密码做测试,将密码字段改为{noop}123456这样的格式
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new MessageDigestPasswordEncoder("MD5");
}
/**
* 认证配置
* anonymous():匿名访问:未登录可以访问,已登录不能访问
* permitAll():有没有认证都能访问:登录或未登录都能访问
* denyAll(): 拒绝
* authenticated():认证之后才能访问
* hasAuthority():包含权限
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
logger.info("configure认证配置");
http
// 关闭csrf(前后端分离项目要关闭此功能)
.csrf().disable()
// 禁用session (前后端分离项目,不通过Session获取SecurityContext)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
// 请求认证配置
.authorizeRequests()
// 允许匿名访问:未登录可以访问,已登录不能访问
.antMatchers("/sys/user/login").anonymous()
.antMatchers("/*.svg*","/*.png*","/*/*.jpg","/*.js*","/*.css*","/swagger-ui.html","/swagger-resources/**","/v2/api-docs").permitAll()// 登录或未登录都能访问
// 任意用户,认证之后才可以访问(除上面外的)
.anyRequest().authenticated();
// 添加token过滤器
http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
// 配置异常处理器
http.exceptionHandling()
// 认证失败
.authenticationEntryPoint(authenticationEntryPoint)
// 授权失败
.accessDeniedHandler(accessDeniedHandler);
// spring security 允许跨域
http.cors();
}
/**
* 注入AuthenticationManager 进行用户认证
*/
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
logger.info("AuthenticationManager进行用户认证");
return super.authenticationManagerBean();
}
}
二、enums
package org.example.common.enums;
public enum RespondCodeEnum {
SUCCESS(200, "成功"),
PARAMS_ERROR(400, "请求参数异常"),
NEED_LOGIN(401, "token过期请重新登录"),
NO_OPERATOR_AUTH(402, "没有访问权限"),
SYSTEM_ERROR(500, "系统异常");
int code;
String msg;
RespondCodeEnum(int code, String errorMessage) {
this.code = code;
this.msg = errorMessage;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
三、JSONResult
package org.example.common;
import org.example.common.enums.RespondCodeEnum;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JSONResult {
private final static Logger logger = LoggerFactory.getLogger(JSONResult.class);
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
// 响应业务状态
private Integer code;
// 响应消息
private String msg;
// 响应中的数据
private Object data;
// 成功时候返回的响应
public static JSONResult success_data(Object data) {
return new JSONResult(data);
}
public static JSONResult success(String msg) {
return new JSONResult(msg);
}
// 错误或者异常情况
public static JSONResult paramsError( String msg) {
return new JSONResult(RespondCodeEnum.PARAMS_ERROR.getCode(),RespondCodeEnum.PARAMS_ERROR.getMsg());
}
public static JSONResult needLogin( String msg) {
return new JSONResult(RespondCodeEnum.NEED_LOGIN.getCode(),RespondCodeEnum.NEED_LOGIN.getMsg());
}
public static JSONResult noOperatorAuth( String msg) {
return new JSONResult(RespondCodeEnum.NO_OPERATOR_AUTH.getCode(),msg);
}
public static JSONResult systemError( String msg) {
return new JSONResult(RespondCodeEnum.SYSTEM_ERROR.getCode(),RespondCodeEnum.SYSTEM_ERROR.getMsg());
}
public JSONResult(Object data, int count) {
this.code = RespondCodeEnum.SUCCESS.getCode();
this.msg = RespondCodeEnum.SUCCESS.getMsg();
this.data = data;
}
public JSONResult(Object data) {
this.code = RespondCodeEnum.SUCCESS.getCode();
this.msg = RespondCodeEnum.SUCCESS.getMsg();
this.data = data;
}
public JSONResult(Integer code,String msg) {
this.code = code;
this.msg = msg;
}
public JSONResult(String msg) {
this.code = RespondCodeEnum.SUCCESS.getCode();
this.msg = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}