From 760bb924794f4bb400f67d1c089aee402d06004b Mon Sep 17 00:00:00 2001
From: bunny <1319900154@qq.com>
Date: Sat, 27 Apr 2024 00:42:06 +0800
Subject: [PATCH] =?UTF-8?q?feat(=E4=BF=AE=E6=94=B9):=20:rocket:=20?=
=?UTF-8?q?=E4=BF=AE=E6=94=B9springSecurity?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.idea/misc.xml | 2 +-
.../atguigu/common/utlis/BaseContext.java} | 5 ++-
.../target/classes/com/atguigu/CodeGet.class | Bin 4085 -> 0 bytes
.../atguigu/config/MybatisPlusConfig.class | Bin 1867 -> 0 bytes
.../atguigu/constant/MessageConstant.class | Bin 2135 -> 0 bytes
.../com/atguigu/context/BaseContext.class | Bin 1484 -> 0 bytes
.../security/config/WebSecurityConfig.java | 15 ++++----
.../atguigu/security/custom/CustomUser.java | 2 --
.../filter/TokenAuthenticationFilter.java | 6 ++--
.../UserDetailsService.java | 2 +-
.../service/impl/UserDetailsServiceImpl.java | 2 +-
service-oa/target/classes/application-dev.yml | 21 -----------
service-oa/target/classes/application.yml | 34 ------------------
service-oa/target/classes/banner.txt | 16 ---------
service-oa/target/classes/favicon.ico | Bin 17014 -> 0 bytes
15 files changed, 14 insertions(+), 91 deletions(-)
rename common/{spring-security/src/main/java/com/atguigu/security/custom/LoginUserInfoHelper.java => common-util/src/main/java/com/atguigu/common/utlis/BaseContext.java} (89%)
delete mode 100644 common/service-util/target/classes/com/atguigu/CodeGet.class
delete mode 100644 common/service-util/target/classes/com/atguigu/config/MybatisPlusConfig.class
delete mode 100644 common/service-util/target/classes/com/atguigu/constant/MessageConstant.class
delete mode 100644 common/service-util/target/classes/com/atguigu/context/BaseContext.class
rename common/spring-security/src/main/java/com/atguigu/security/{custom => service}/UserDetailsService.java (93%)
delete mode 100644 service-oa/target/classes/application-dev.yml
delete mode 100644 service-oa/target/classes/application.yml
delete mode 100644 service-oa/target/classes/banner.txt
delete mode 100644 service-oa/target/classes/favicon.ico
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 9134c12..79f13d2 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -9,5 +9,5 @@
-
+
\ No newline at end of file
diff --git a/common/spring-security/src/main/java/com/atguigu/security/custom/LoginUserInfoHelper.java b/common/common-util/src/main/java/com/atguigu/common/utlis/BaseContext.java
similarity index 89%
rename from common/spring-security/src/main/java/com/atguigu/security/custom/LoginUserInfoHelper.java
rename to common/common-util/src/main/java/com/atguigu/common/utlis/BaseContext.java
index 039036d..b0dc6d9 100644
--- a/common/spring-security/src/main/java/com/atguigu/security/custom/LoginUserInfoHelper.java
+++ b/common/common-util/src/main/java/com/atguigu/common/utlis/BaseContext.java
@@ -1,7 +1,6 @@
-package com.atguigu.security.custom;
-
-public class LoginUserInfoHelper {
+package com.atguigu.common.utlis;
+public class BaseContext {
private static final ThreadLocal userId = new ThreadLocal();
private static final ThreadLocal username = new ThreadLocal();
diff --git a/common/service-util/target/classes/com/atguigu/CodeGet.class b/common/service-util/target/classes/com/atguigu/CodeGet.class
deleted file mode 100644
index b9e4bfa2afb39c1234b5938560fd5e198c681722..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4085
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
CMv;2}
diff --git a/common/service-util/target/classes/com/atguigu/context/BaseContext.class b/common/service-util/target/classes/com/atguigu/context/BaseContext.class
deleted file mode 100644
index be58c65410bf62645a8c8d2ba3b9865028c9f80f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1484
zcmai!YflqF6o%iSmu;5?DilF1mWyaxg?d3mTOmqfLQ*dYSmP(Mw3D)=?IznT`m?+w
zkZ5B3?2j_Ov)jv7Ht|Du=FFUP-e=C7>F+<^e*)OVGaX}yXown!AufR7+0~|
z4VCq(fjP`Gw4*|2bC)CYRpqx};JP|{+>tH&OsXR;8n~g(7yoEFa=)&YmJBSbCC#k2
ztoD9gMMeaY2UeqPx?M*K1la;dEC+-YTWO~x5Z$xu44JA}ZTY&}I+o6%dEDg6v{#m@
z=~&9{Ek@lFt0S;n`A@x>ILSi2>(zXEq+Fgh9axUO!%VO!-hRHyBOdiHE%h%tJLHvg
zPwe_z(=l7pl@75Czi|Deir~FhH(#tj*N*&Z4g&fcIs=~jRTa>QH!u=My=n_g_#(rt
za;@2GO#Q&_IyL#yQuRv(+HXTO1+Oi^CI=!|P+bdwRa#@XNt?GkV)Kdv_BiK!7W}R;
zqR3Hjj1?{*zIZ8a@vF9hC~otsg6V)9@*I;W;0{+*@QSws=wG3oW8xQPK66!Im|>j$
zcd|<-f&INWnh9(W5V*%*OwdsB_Xq5&J$cQOzoxSJ+J3ef
zI;I)$AdEK?&O1;4hhe;#Fy0J#7e{zEgS?v_@1rnY%3tDLqT@34x59X{;k;|~e;me}
z4dcy|w=lxH9pv5ic%OvvQvMR}IvqFIhEE3pyWTAV*&mqvaDkO?&<3;2V3r+T6#s3g
Q8H3IgX~GGVXpf=%7fh!EL;wH)
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 8a3312c..4c62ec2 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
@@ -38,20 +38,17 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 这是配置的关键,决定哪些接口开启防护,哪些接口绕过防护
- http
- // 关闭csrf跨站请求伪造
- .csrf().disable()
- // 开启跨域以便前端调用接口
- .cors().and()
+ http.csrf().disable() // 关闭csrf跨站请求伪造
+ .cors().and()// 开启跨域以便前端调用接口
.authorizeRequests()
// 指定某些接口不需要通过验证即可访问。登陆接口肯定是不需要认证的
- //.antMatchers("/admin/system/index/login").permitAll()
+ .antMatchers("/admin/system/index/login").permitAll()
// 这里意思是其它所有接口需要认证才能访问
.anyRequest().authenticated()
.and()
- // TokenAuthenticationFilter放到UsernamePasswordAuthenticationFilter的前面,这样做就是为了除了登录的时候去查询数据库外,其他时候都用token进行认证。
- .addFilterBefore(new TokenAuthenticationFilter(redisTemplate),
- UsernamePasswordAuthenticationFilter.class)
+ // TokenAuthenticationFilter放到UsernamePasswordAuthenticationFilter的前面
+ // 这样做就是为了除了登录的时候去查询数据库外,其他时候都用token进行认证。
+ .addFilterBefore(new TokenAuthenticationFilter(redisTemplate), UsernamePasswordAuthenticationFilter.class)
.addFilter(new TokenLoginFilter(authenticationManager(), redisTemplate));
// 禁用session
diff --git a/common/spring-security/src/main/java/com/atguigu/security/custom/CustomUser.java b/common/spring-security/src/main/java/com/atguigu/security/custom/CustomUser.java
index 1969f79..3c752ed 100644
--- a/common/spring-security/src/main/java/com/atguigu/security/custom/CustomUser.java
+++ b/common/spring-security/src/main/java/com/atguigu/security/custom/CustomUser.java
@@ -11,7 +11,6 @@ import java.util.Collection;
@Setter
@Getter
public class CustomUser extends User {
-
/**
* 我们自己的用户实体对象,要调取用户信息时直接获取这个实体对象。(这里我就不写get/set方法了)
*/
@@ -21,5 +20,4 @@ public class CustomUser extends User {
super(sysUser.getUsername(), sysUser.getPassword(), authorities);
this.sysUser = sysUser;
}
-
}
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 e851f99..448bff0 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
@@ -3,9 +3,9 @@ package com.atguigu.security.filter;
import com.alibaba.fastjson.JSON;
import com.atguigu.common.result.Result;
import com.atguigu.common.result.ResultCodeEnum;
+import com.atguigu.common.utlis.BaseContext;
import com.atguigu.common.utlis.JwtHelper;
import com.atguigu.common.utlis.ResponseUtil;
-import com.atguigu.security.custom.LoginUserInfoHelper;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
@@ -56,8 +56,8 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
String username = JwtHelper.getUserName(token);
if (!StringUtils.isEmpty(username)) {
// 当前用户信息放到ThreadLocal里面
- LoginUserInfoHelper.setUserId(JwtHelper.getUserId(token));
- LoginUserInfoHelper.setUsername(username);
+ BaseContext.setUserId(JwtHelper.getUserId(token));
+ BaseContext.setUsername(username);
// 通过username从redis获取权限数据
String authString = (String) redisTemplate.opsForValue().get(username);
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/service/UserDetailsService.java
similarity index 93%
rename from common/spring-security/src/main/java/com/atguigu/security/custom/UserDetailsService.java
rename to common/spring-security/src/main/java/com/atguigu/security/service/UserDetailsService.java
index e0057c4..9185009 100644
--- a/common/spring-security/src/main/java/com/atguigu/security/custom/UserDetailsService.java
+++ b/common/spring-security/src/main/java/com/atguigu/security/service/UserDetailsService.java
@@ -1,4 +1,4 @@
-package com.atguigu.security.custom;
+package com.atguigu.security.service;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
diff --git a/service-oa/src/main/java/com/atguigu/auth/service/impl/UserDetailsServiceImpl.java b/service-oa/src/main/java/com/atguigu/auth/service/impl/UserDetailsServiceImpl.java
index 64460ad..dcea726 100644
--- a/service-oa/src/main/java/com/atguigu/auth/service/impl/UserDetailsServiceImpl.java
+++ b/service-oa/src/main/java/com/atguigu/auth/service/impl/UserDetailsServiceImpl.java
@@ -5,9 +5,9 @@ import com.atguigu.constant.MessageConstant;
import com.atguigu.exception.BunnyException;
import com.atguigu.model.system.SysUser;
import com.atguigu.security.custom.CustomUser;
+import com.atguigu.security.service.UserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
diff --git a/service-oa/target/classes/application-dev.yml b/service-oa/target/classes/application-dev.yml
deleted file mode 100644
index 2ea6574..0000000
--- a/service-oa/target/classes/application-dev.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-server:
- port: 8800
-
-bunny:
- datasource:
- host: 106.15.251.123
- port: 3305
- sqlData: guigu-oa
- username: root
- password: "02120212"
-
-# nacos:
-# server-addr: z-bunny.cn:8848
-# discovery:
-# namespace: ssyx
-#
-# minio:
-# endpointUrl: "http://129.211.31.58:9000"
-# bucket-name: ssyx
-# accessKey: bunny
-# secretKey: "02120212"
\ No newline at end of file
diff --git a/service-oa/target/classes/application.yml b/service-oa/target/classes/application.yml
deleted file mode 100644
index 856c064..0000000
--- a/service-oa/target/classes/application.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-server:
- port: 8800
-
-spring:
- application:
- name: service-oa
- profiles:
- active: dev
-
- datasource:
- type: com.zaxxer.hikari.HikariDataSource
- driver-class-name: com.mysql.cj.jdbc.Driver
- url: jdbc:mysql://${bunny.datasource.host}:${bunny.datasource.port}/${bunny.datasource.sqlData}?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true
- username: ${bunny.datasource.username}
- password: ${bunny.datasource.password}
-
- jackson:
- date-format: yyyy-MM-dd HH:mm:ss
- time-zone: GMT+8
-
-mybatis-plus:
- mapper-locations: classpath:mapper/*.xml
- configuration:
- log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 查看日志
-
-logging:
- level:
- com.atguigu.auth.mapper: debug
- com.atguigu.auth.controller: info
- com.atguigu.auth.service: info
- pattern:
- dateformat: HH:mm:ss:SSS
- file:
- path: "logs/${spring.application.name}"
\ No newline at end of file
diff --git a/service-oa/target/classes/banner.txt b/service-oa/target/classes/banner.txt
deleted file mode 100644
index cc77fc2..0000000
--- a/service-oa/target/classes/banner.txt
+++ /dev/null
@@ -1,16 +0,0 @@
------------------▄██-█▄---------
------------------███▄██▄--------
------------------███████--------
------------------▀███████-------
--------------------██████▄▄-----
--------------------█████████▄---
--------------------██████▄████--
--------▄███████████████████████-
------▄███████████████████████▀--
----▄██████████████████████------
----███████████████████████------
----███████████████████████------
--▄▄██████████████████████▀------
--█████████████████▀█████--------
--▀██████████████▀▀-▀█████▄------
--------▀▀▀▀▀▀▀▀▀------▀▀▀▀------
\ No newline at end of file
diff --git a/service-oa/target/classes/favicon.ico b/service-oa/target/classes/favicon.ico
deleted file mode 100644
index 2f64da52ae22180ce73a6cda8d6724f8ad91a185..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 17014
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