diff --git a/common/common-util/src/main/java/com/atguigu/common/result/ResultCodeEnum.java b/common/common-util/src/main/java/com/atguigu/common/result/ResultCodeEnum.java
index 679f061..e1612e8 100644
--- a/common/common-util/src/main/java/com/atguigu/common/result/ResultCodeEnum.java
+++ b/common/common-util/src/main/java/com/atguigu/common/result/ResultCodeEnum.java
@@ -18,7 +18,7 @@ public enum ResultCodeEnum {
FAIL(201, "失败"),
SERVICE_ERROR(2012, "服务异常"),
DATA_ERROR(204, "数据异常"),
- LOGIN_ERROR(205, "认证失败"),
+ LOGIN_ERROR(204, "认证失败"),
LOGIN_AUTH(208, "未登陆"),
PERMISSION(209, "没有权限");
diff --git a/common/service-util/pom.xml b/common/service-util/pom.xml
index 51dc7c5..08a4497 100644
--- a/common/service-util/pom.xml
+++ b/common/service-util/pom.xml
@@ -32,6 +32,12 @@
com.github.xiaoymin
knife4j-spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+ provided
+
diff --git a/common/service-util/src/main/java/com/atguigu/common/execption/GlobalExceptionHandler.java b/common/service-util/src/main/java/com/atguigu/common/config/execption/GlobalExceptionHandler.java
similarity index 59%
rename from common/service-util/src/main/java/com/atguigu/common/execption/GlobalExceptionHandler.java
rename to common/service-util/src/main/java/com/atguigu/common/config/execption/GlobalExceptionHandler.java
index aae03eb..37e1152 100644
--- a/common/service-util/src/main/java/com/atguigu/common/execption/GlobalExceptionHandler.java
+++ b/common/service-util/src/main/java/com/atguigu/common/config/execption/GlobalExceptionHandler.java
@@ -1,6 +1,8 @@
-package com.atguigu.common.execption;
+package com.atguigu.common.config.execption;
import com.atguigu.common.result.Result;
+import com.atguigu.common.result.ResultCodeEnum;
+import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@@ -18,6 +20,12 @@ import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class GlobalExceptionHandler {
+ /**
+ * 全局异常处理,执行方法
+ *
+ * @param e
+ * @return
+ */
@ExceptionHandler(Exception.class)
@ResponseBody
public Result error(Exception e) {
@@ -25,6 +33,12 @@ public class GlobalExceptionHandler {
return Result.fail();
}
+ /**
+ * 特定异常处理类
+ *
+ * @param e
+ * @return
+ */
@ExceptionHandler(ArithmeticException.class)
@ResponseBody
public Result error(ArithmeticException e) {
@@ -32,10 +46,28 @@ public class GlobalExceptionHandler {
return Result.fail().message("执行了特定异常处理");
}
+ /**
+ * 自定义异常处理类
+ *
+ * @param e
+ * @return
+ */
@ExceptionHandler(GuiguException.class)
@ResponseBody
public Result error(GuiguException e) {
e.printStackTrace();
return Result.fail().message(e.getMsg()).code(e.getCode());
}
+
+ /**
+ * spring security异常
+ *
+ * @param e
+ * @return
+ */
+ @ExceptionHandler(AccessDeniedException.class)
+ @ResponseBody
+ public Result error(AccessDeniedException e) throws AccessDeniedException {
+ return Result.build(null, ResultCodeEnum.PERMISSION);
+ }
}
diff --git a/common/service-util/src/main/java/com/atguigu/common/execption/GuiguException.java b/common/service-util/src/main/java/com/atguigu/common/config/execption/GuiguException.java
similarity index 95%
rename from common/service-util/src/main/java/com/atguigu/common/execption/GuiguException.java
rename to common/service-util/src/main/java/com/atguigu/common/config/execption/GuiguException.java
index f3631b1..d76a370 100644
--- a/common/service-util/src/main/java/com/atguigu/common/execption/GuiguException.java
+++ b/common/service-util/src/main/java/com/atguigu/common/config/execption/GuiguException.java
@@ -1,4 +1,4 @@
-package com.atguigu.common.execption;
+package com.atguigu.common.config.execption;
import com.atguigu.common.result.ResultCodeEnum;
import lombok.Data;
diff --git a/common/spring-security/pom.xml b/common/spring-security/pom.xml
index 7bf3fee..7178b3c 100644
--- a/common/spring-security/pom.xml
+++ b/common/spring-security/pom.xml
@@ -38,5 +38,10 @@
spring-boot-starter-web
provided
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
diff --git a/common/spring-security/src/main/java/com/atguigu/security/config/WebSecurityConfig.java b/common/spring-security/src/main/java/com/atguigu/security/config/WebSecurityConfig.java
index 7c3edc7..89402ac 100644
--- a/common/spring-security/src/main/java/com/atguigu/security/config/WebSecurityConfig.java
+++ b/common/spring-security/src/main/java/com/atguigu/security/config/WebSecurityConfig.java
@@ -1,8 +1,22 @@
package com.atguigu.security.config;
+import com.atguigu.security.custom.CustomMd5PasswordEncoder;
+import com.atguigu.security.filter.TokenAuthenticationFilter;
+import com.atguigu.security.filter.TokenLoginFilter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* ClassName: WebSecurityConfig
@@ -14,6 +28,66 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
@Configuration
//@EnableWebSecurity是开启SpringSecurity的默认行为
@EnableWebSecurity
+//开启基于方法的安全认证机制,在web层的controller启用注解机制的安全确认
+@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+ /**
+ * 装载的是 org.springframework.security.core.userdetails.UserDetailsService;
+ */
+ @Autowired
+ private UserDetailsService userDetailsService;
+
+ @Autowired
+ private CustomMd5PasswordEncoder customMd5PasswordEncoder;
+
+ @Autowired
+ private RedisTemplate redisTemplate;
+
+ @Bean
+ @Override
+ protected AuthenticationManager authenticationManager() throws Exception {
+ return super.authenticationManager();
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ // 这是配置的关键,决定哪些接口开启防护,哪些接口绕过防护
+ http
+ //关闭csrf跨站请求伪造
+ .csrf().disable()
+ // 开启跨域以便前端调用接口
+ .cors().and()
+ .authorizeRequests()
+ // 指定某些接口不需要通过验证即可访问。登陆接口肯定是不需要认证的
+ .antMatchers("/admin/system/index/login").permitAll()
+ // 这里意思是其它所有接口需要认证才能访问
+ .anyRequest().authenticated()
+ .and()
+ //TokenAuthenticationFilter放到UsernamePasswordAuthenticationFilter的前面,这样做就是为了除了登录的时候去查询数据库外,其他时候都用token进行认证。
+ .addFilterBefore(new TokenAuthenticationFilter(redisTemplate), UsernamePasswordAuthenticationFilter.class)
+ .addFilter(new TokenLoginFilter(authenticationManager(), redisTemplate));
+
+ //禁用session
+ http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
+ }
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ // 指定UserDetailService和加密器
+ auth.userDetailsService(userDetailsService)
+ .passwordEncoder(customMd5PasswordEncoder);
+ }
+
+ /**
+ * 配置哪些请求不拦截
+ * 排除swagger相关请求
+ *
+ * @param web
+ * @throws Exception
+ */
+ @Override
+ public void configure(WebSecurity web) throws Exception {
+ web.ignoring().antMatchers("/favicon.ico", "/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**", "/doc.html");
+ }
}
diff --git a/common/spring-security/src/main/java/com/atguigu/security/custom/UserDetailsService.java b/common/spring-security/src/main/java/com/atguigu/security/custom/UserDetailsService.java
index 2463548..e8bef49 100644
--- a/common/spring-security/src/main/java/com/atguigu/security/custom/UserDetailsService.java
+++ b/common/spring-security/src/main/java/com/atguigu/security/custom/UserDetailsService.java
@@ -10,7 +10,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
* @author yovinchen
* @Create 2023/6/10 23:28
*/
-public interface UserDetailsService {
+public interface UserDetailsService extends org.springframework.security.core.userdetails.UserDetailsService {
/**
* 根据用户名获取用户对象(获取不到直接抛异常)
@@ -19,5 +19,6 @@ public interface UserDetailsService {
* @return
* @throws UsernameNotFoundException
*/
+ @Override
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
diff --git a/common/spring-security/src/main/java/com/atguigu/security/filter/TokenAuthenticationFilter.java b/common/spring-security/src/main/java/com/atguigu/security/filter/TokenAuthenticationFilter.java
index a215cc2..d60425e 100644
--- a/common/spring-security/src/main/java/com/atguigu/security/filter/TokenAuthenticationFilter.java
+++ b/common/spring-security/src/main/java/com/atguigu/security/filter/TokenAuthenticationFilter.java
@@ -1,10 +1,13 @@
package com.atguigu.security.filter;
+import com.alibaba.fastjson.JSON;
import com.atguigu.common.jwt.JwtHelper;
import com.atguigu.common.result.Result;
import com.atguigu.common.result.ResultCodeEnum;
import com.atguigu.common.utils.ResponseUtil;
+import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
@@ -14,7 +17,9 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
-import java.util.Collections;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
/**
* ClassName: TokenAuthenticationFilter
@@ -26,8 +31,10 @@ import java.util.Collections;
*/
public class TokenAuthenticationFilter extends OncePerRequestFilter {
- public TokenAuthenticationFilter() {
+ private RedisTemplate redisTemplate;
+ public TokenAuthenticationFilter(RedisTemplate redisTemplate) {
+ this.redisTemplate = redisTemplate;
}
@Override
@@ -55,8 +62,22 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
if (!StringUtils.isEmpty(token)) {
String useruame = JwtHelper.getUsername(token);
logger.info("useruame:" + useruame);
+ //认证成功
if (!StringUtils.isEmpty(useruame)) {
- return new UsernamePasswordAuthenticationToken(useruame, null, Collections.emptyList());
+ //通过username从reids中获取权限数据
+ String authString = (String) redisTemplate.opsForValue().get(useruame);
+ //将redis中获取的字符串权限数据转换为 ArrayList
+ if (!StringUtils.isEmpty(authString)) {
+ List