|
|
@@ -1,35 +1,34 @@
|
|
|
package cn.reghao.bnt.web.admin.security;
|
|
|
|
|
|
-import cn.reghao.bnt.web.admin.security.access.MyAccessDecisionManager;
|
|
|
-import cn.reghao.bnt.web.admin.security.access.MySecurityMetadataSource;
|
|
|
import cn.reghao.bnt.web.admin.security.filter.LoginRedirectFilter;
|
|
|
import cn.reghao.bnt.web.admin.security.form.AccountAuthFilter;
|
|
|
import cn.reghao.bnt.web.admin.security.form.AccountAuthProvider;
|
|
|
+import cn.reghao.bnt.web.admin.security.session.MySessionAuthenticationStrategy;
|
|
|
import cn.reghao.bnt.web.admin.service.AccountLoginService;
|
|
|
+import cn.reghao.bnt.web.admin.service.MenuService;
|
|
|
import org.springframework.context.annotation.Bean;
|
|
|
import org.springframework.context.annotation.Configuration;
|
|
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
|
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
|
|
|
import org.springframework.security.authentication.AuthenticationManager;
|
|
|
-import org.springframework.security.config.annotation.ObjectPostProcessor;
|
|
|
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
|
|
-import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
|
|
+import org.springframework.security.authorization.AuthorizationDecision;
|
|
|
+import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
|
|
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.GrantedAuthority;
|
|
|
import org.springframework.security.core.session.SessionRegistry;
|
|
|
-import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
|
|
|
+import org.springframework.security.web.SecurityFilterChain;
|
|
|
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
|
|
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
|
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
|
|
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
|
|
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
|
|
import org.springframework.security.web.authentication.session.*;
|
|
|
-import org.springframework.security.web.context.SecurityContextPersistenceFilter;
|
|
|
+import org.springframework.security.web.context.SecurityContextHolderFilter;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.Collection;
|
|
|
import java.util.List;
|
|
|
|
|
|
/**
|
|
|
@@ -40,8 +39,7 @@ import java.util.List;
|
|
|
*/
|
|
|
@Configuration
|
|
|
@EnableWebSecurity
|
|
|
-@EnableGlobalMethodSecurity(prePostEnabled = true) // 调用方法时检查权限
|
|
|
-public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|
|
+public class WebSecurityConfig {
|
|
|
private final String loginPage = "/bg/login";
|
|
|
private final String loginApi = "/bg/login";
|
|
|
private final String logoutApi = "/bg/logout";
|
|
|
@@ -52,15 +50,13 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|
|
private final AuthenticationFailureHandler failureHandler;
|
|
|
private final LogoutHandler logoutHandler;
|
|
|
private final LogoutSuccessHandler logoutSuccessHandler;
|
|
|
- private SessionRegistry sessionRegistry;
|
|
|
- private final MyAccessDecisionManager myAccessDecisionManager;
|
|
|
- private final MySecurityMetadataSource mySecurityMetadataSource;
|
|
|
+ private final SessionRegistry sessionRegistry;
|
|
|
+ private final MenuService menuService;
|
|
|
|
|
|
public WebSecurityConfig(AccountAuthProvider userAuthProvider, AccountLoginService accountLoginService,
|
|
|
AuthenticationSuccessHandler successHandler, AuthenticationFailureHandler failureHandler,
|
|
|
LogoutHandler logoutHandler, LogoutSuccessHandler logoutSuccessHandler,
|
|
|
- SessionRegistry sessionRegistry, MyAccessDecisionManager myAccessDecisionManager,
|
|
|
- MySecurityMetadataSource mySecurityMetadataSource) {
|
|
|
+ SessionRegistry sessionRegistry, MenuService menuService) {
|
|
|
this.userAuthProvider = userAuthProvider;
|
|
|
this.accountLoginService = accountLoginService;
|
|
|
this.successHandler = successHandler;
|
|
|
@@ -68,8 +64,73 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|
|
this.logoutHandler = logoutHandler;
|
|
|
this.logoutSuccessHandler = logoutSuccessHandler;
|
|
|
this.sessionRegistry = sessionRegistry;
|
|
|
- this.myAccessDecisionManager = myAccessDecisionManager;
|
|
|
- this.mySecurityMetadataSource = mySecurityMetadataSource;
|
|
|
+ this.menuService = menuService;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Bean
|
|
|
+ public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
|
|
|
+ http
|
|
|
+ /*.authorizeHttpRequests(request -> request
|
|
|
+ .requestMatchers("/dist/**").permitAll()
|
|
|
+ .requestMatchers("/bg/dist/**").permitAll()
|
|
|
+ // 不需要认证的接口
|
|
|
+ .requestMatchers("/bg/api/actuator/**").permitAll()
|
|
|
+ .requestMatchers(loginApi).permitAll()
|
|
|
+ .requestMatchers(logoutApi).permitAll()
|
|
|
+ .requestMatchers("/bg/code/**").permitAll()
|
|
|
+ .requestMatchers("/bg/api/oss/**").permitAll()
|
|
|
+ // 需要认证的接口
|
|
|
+ .requestMatchers("/bg/**").authenticated()
|
|
|
+ // 不需要认证的接口
|
|
|
+ .anyRequest().permitAll())*/
|
|
|
+ .authorizeHttpRequests(register -> register.anyRequest().access((authentication, object) -> {
|
|
|
+ String method = object.getRequest().getMethod();
|
|
|
+ if (method == null) {
|
|
|
+ method = "";
|
|
|
+ }
|
|
|
+ //获取当前请求的 URL 地址
|
|
|
+ String requestUrl = object.getRequest().getRequestURI();
|
|
|
+ if (requestUrl.startsWith("/dist/") || requestUrl.startsWith("/bg/dist/")) {
|
|
|
+ // 放行静态资源
|
|
|
+ return new AuthorizationDecision(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取可访问 url 的角色集合
|
|
|
+ List<String> roles = menuService.getRolesByUrl(method, requestUrl);
|
|
|
+ if (roles.isEmpty()) {
|
|
|
+ return new AuthorizationDecision(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取当前登录用户的角色
|
|
|
+ Collection<? extends GrantedAuthority> authorities = authentication.get().getAuthorities();
|
|
|
+ for (GrantedAuthority authority : authorities) {
|
|
|
+ for (String role : roles) {
|
|
|
+ if (authority.getAuthority().equals(role)) {
|
|
|
+ //说明当前登录用户具备当前请求所需要的角色
|
|
|
+ return new AuthorizationDecision(true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return new AuthorizationDecision(false);
|
|
|
+ }))
|
|
|
+ //.securityContext((context) -> context.securityContextRepository(new HttpSessionSecurityContextRepository()))
|
|
|
+ .securityContext((securityContext) -> securityContext.requireExplicitSave(true))
|
|
|
+ .addFilterAfter(new LoginRedirectFilter(), SecurityContextHolderFilter.class)
|
|
|
+ .addFilterBefore(accountAuthFilter(authenticationManager), UsernamePasswordAuthenticationFilter.class)
|
|
|
+ .formLogin().disable()
|
|
|
+ .logout().logoutUrl(logoutApi).addLogoutHandler(logoutHandler).logoutSuccessHandler(logoutSuccessHandler)
|
|
|
+ .and()
|
|
|
+ .exceptionHandling().authenticationEntryPoint(new MyAuthenticationEntryPoint())
|
|
|
+ .and()
|
|
|
+ .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
|
|
|
+ .and()
|
|
|
+ .rememberMe().disable()
|
|
|
+ .cors().disable()
|
|
|
+ .csrf().disable()
|
|
|
+ .headers().disable()
|
|
|
+ .authenticationProvider(userAuthProvider);
|
|
|
+
|
|
|
+ return http.build();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -79,14 +140,14 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|
|
* @return
|
|
|
* @date 2023-08-02 11:09:45
|
|
|
*/
|
|
|
- @Override
|
|
|
+ /*@Override
|
|
|
public void configure(WebSecurity web) {
|
|
|
web.ignoring()
|
|
|
.antMatchers("/dist/**")
|
|
|
.antMatchers("/bg/dist/**");
|
|
|
- }
|
|
|
+ }*/
|
|
|
|
|
|
- @Override
|
|
|
+ /*@Override
|
|
|
public void configure(HttpSecurity http) throws Exception {
|
|
|
// 在 FilterSecurityInterceptor 中用于权限判定
|
|
|
http.authorizeRequests()
|
|
|
@@ -125,7 +186,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|
|
|
|
|
// 配置 ExceptionTranslationFilter, 登入认证接口失败时的处理, 不会重定向到 loginPage
|
|
|
http.exceptionHandling()
|
|
|
- .authenticationEntryPoint(new ExceptionAuthenticationEntryPoint());
|
|
|
+ .authenticationEntryPoint(new MyAuthenticationEntryPoint());
|
|
|
|
|
|
// 配置 SessionManagementFilter
|
|
|
http.sessionManagement()
|
|
|
@@ -133,8 +194,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|
|
|
|
|
// 配置 RememberMeAuthenticationFilter, 禁用 RememberMeAuthenticationFilter
|
|
|
http.rememberMe().disable();
|
|
|
- /*.key("DExNzAyNTQ2Nzo3NDI3MTNhYmM5MGE5")
|
|
|
- .rememberMeParameter("rememberMe");*/
|
|
|
+ *//*.key("DExNzAyNTQ2Nzo3NDI3MTNhYmM5MGE5")
|
|
|
+ .rememberMeParameter("rememberMe");*//*
|
|
|
|
|
|
// 配置 CorsFilter, 禁用 CorsFilter
|
|
|
http.cors().disable();
|
|
|
@@ -144,7 +205,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|
|
|
|
|
// 配置 HeaderWriterFilter, 禁用 HeaderWriterFilter
|
|
|
http.headers().disable();
|
|
|
- }
|
|
|
+ }*/
|
|
|
|
|
|
/**
|
|
|
* 配置认证管理器
|
|
|
@@ -154,9 +215,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|
|
* @date 2021-07-25 下午2:28
|
|
|
*/
|
|
|
@Bean
|
|
|
- @Override
|
|
|
- public AuthenticationManager authenticationManagerBean() throws Exception {
|
|
|
- return super.authenticationManagerBean();
|
|
|
+ public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
|
|
|
+ return authenticationConfiguration.getAuthenticationManager();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -166,10 +226,10 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|
|
* @return
|
|
|
* @date 2021-07-25 下午2:31
|
|
|
*/
|
|
|
- @Override
|
|
|
+ /*@Override
|
|
|
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
|
|
auth.authenticationProvider(userAuthProvider);
|
|
|
- }
|
|
|
+ }*/
|
|
|
|
|
|
/**
|
|
|
* 配置账号密码登入 filter
|
|
|
@@ -178,9 +238,9 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|
|
* @return
|
|
|
* @date 2022-07-06 上午9:54
|
|
|
*/
|
|
|
- public AccountAuthFilter accountAuthFilter() throws Exception {
|
|
|
+ public AccountAuthFilter accountAuthFilter(AuthenticationManager authenticationManager) throws Exception {
|
|
|
AccountAuthFilter filter = new AccountAuthFilter(loginApi, "POST", accountLoginService);
|
|
|
- filter.setAuthenticationManager(super.authenticationManager());
|
|
|
+ filter.setAuthenticationManager(authenticationManager);
|
|
|
filter.setAuthenticationSuccessHandler(successHandler);
|
|
|
filter.setAuthenticationFailureHandler(failureHandler);
|
|
|
filter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy(sessionRegistry));
|
|
|
@@ -201,6 +261,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|
|
authenticationStrategies.add(new SessionFixationProtectionStrategy());
|
|
|
// 认证成功后将认证信息注册到 SessionRegistry
|
|
|
authenticationStrategies.add(new RegisterSessionAuthenticationStrategy(sessionRegistry));
|
|
|
+ authenticationStrategies.add(new MySessionAuthenticationStrategy());
|
|
|
|
|
|
return new CompositeSessionAuthenticationStrategy(authenticationStrategies);
|
|
|
}
|