dengzedong
2024-12-19 85b2001c0ec2f1adc598db3bf47ad457dcca7074
提交 | 用户 | 时间
e7c126 1 package com.iailab.framework.security.config;
H 2
d9f9ba 3 import cn.hutool.extra.spring.SpringUtil;
e7c126 4 import com.iailab.framework.security.core.aop.PreAuthenticatedAspect;
H 5 import com.iailab.framework.security.core.context.TransmittableThreadLocalSecurityContextHolderStrategy;
6 import com.iailab.framework.security.core.filter.TokenAuthenticationFilter;
7 import com.iailab.framework.security.core.handler.AccessDeniedHandlerImpl;
8 import com.iailab.framework.security.core.handler.AuthenticationEntryPointImpl;
9 import com.iailab.framework.security.core.service.SecurityFrameworkService;
10 import com.iailab.framework.security.core.service.SecurityFrameworkServiceImpl;
11 import com.iailab.framework.web.core.handler.GlobalExceptionHandler;
12 import com.iailab.module.system.api.oauth2.OAuth2TokenApi;
13 import com.iailab.module.system.api.permission.PermissionApi;
d9f9ba 14 import org.springframework.beans.factory.annotation.Qualifier;
e7c126 15 import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
H 16 import org.springframework.boot.autoconfigure.AutoConfiguration;
17 import org.springframework.boot.autoconfigure.AutoConfigureOrder;
18 import org.springframework.boot.context.properties.EnableConfigurationProperties;
19 import org.springframework.context.annotation.Bean;
20 import org.springframework.security.core.context.SecurityContextHolder;
21 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
22 import org.springframework.security.crypto.password.PasswordEncoder;
23 import org.springframework.security.web.AuthenticationEntryPoint;
24 import org.springframework.security.web.access.AccessDeniedHandler;
25
26 import javax.annotation.Resource;
27
28 /**
29  * Spring Security 自动配置类,主要用于相关组件的配置
30  *
31  * 注意,不能和 {@link IailabWebSecurityConfigurerAdapter} 用一个,原因是会导致初始化报错。
32  * 参见 https://stackoverflow.com/questions/53847050/spring-boot-delegatebuilder-cannot-be-null-on-autowiring-authenticationmanager 文档。
33  *
34  * @author iailab
35  */
36 @AutoConfiguration
37 @AutoConfigureOrder(-1) // 目的:先于 Spring Security 自动配置,避免一键改包后,org.* 基础包无法生效
38 @EnableConfigurationProperties(SecurityProperties.class)
39 public class IailabSecurityAutoConfiguration {
40
41     @Resource
42     private SecurityProperties securityProperties;
43
44     /**
45      * 处理用户未登录拦截的切面的 Bean
46      */
47     @Bean
48     public PreAuthenticatedAspect preAuthenticatedAspect() {
49         return new PreAuthenticatedAspect();
50     }
51
52     /**
53      * 认证失败处理类 Bean
54      */
55     @Bean
56     public AuthenticationEntryPoint authenticationEntryPoint() {
57         return new AuthenticationEntryPointImpl();
58     }
59
60     /**
61      * 权限不够处理器 Bean
62      */
63     @Bean
64     public AccessDeniedHandler accessDeniedHandler() {
65         return new AccessDeniedHandlerImpl();
66     }
67
68     /**
69      * Spring Security 加密器
70      * 考虑到安全性,这里采用 BCryptPasswordEncoder 加密器
71      *
72      * @see <a href="http://stackabuse.com/password-encoding-with-spring-security/">Password Encoding with Spring Security</a>
73      */
74     @Bean
75     public PasswordEncoder passwordEncoder() {
76         return new BCryptPasswordEncoder(securityProperties.getPasswordEncoderLength());
77     }
78
79     /**
80      * Token 认证过滤器 Bean
81      */
82     @Bean
83     public TokenAuthenticationFilter authenticationTokenFilter(GlobalExceptionHandler globalExceptionHandler,
84                                                                OAuth2TokenApi oauth2TokenApi) {
d9f9ba 85         try {
H 86             OAuth2TokenApi oAuth2TokenApi = SpringUtil.getBean("aAuth2TokenApiImpl", OAuth2TokenApi.class);
87             if (oAuth2TokenApi != null) {
88                 oauth2TokenApi = oAuth2TokenApi;
89             }
90         } catch (Exception ignored) {}
e7c126 91         return new TokenAuthenticationFilter(securityProperties, globalExceptionHandler, oauth2TokenApi);
H 92     }
93
94     @Bean("ss") // 使用 Spring Security 的缩写,方便使用
95     public SecurityFrameworkService securityFrameworkService(PermissionApi permissionApi) {
d9f9ba 96         try {
H 97             PermissionApi permissionApiImpl = SpringUtil.getBean("permissionApiImpl", PermissionApi.class);
98             if (permissionApiImpl != null) {
99                 permissionApi = permissionApiImpl;
100             }
101         } catch (Exception ignored) {}
e7c126 102         return new SecurityFrameworkServiceImpl(permissionApi);
H 103     }
104
105     /**
106      * 声明调用 {@link SecurityContextHolder#setStrategyName(String)} 方法,
107      * 设置使用 {@link TransmittableThreadLocalSecurityContextHolderStrategy} 作为 Security 的上下文策略
108      */
109     @Bean
110     public MethodInvokingFactoryBean securityContextHolderMethodInvokingFactoryBean() {
111         MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
112         methodInvokingFactoryBean.setTargetClass(SecurityContextHolder.class);
113         methodInvokingFactoryBean.setTargetMethod("setStrategyName");
114         methodInvokingFactoryBean.setArguments(TransmittableThreadLocalSecurityContextHolderStrategy.class.getName());
115         return methodInvokingFactoryBean;
116     }
117
118 }