11package me .zhengjie .modules .security .config ;
22
3+ import me .zhengjie .annotation .AnonymousAccess ;
4+ import me .zhengjie .config .ElPermissionConfig ;
35import me .zhengjie .modules .security .security .JwtAuthenticationEntryPoint ;
46import me .zhengjie .modules .security .security .JwtAuthorizationTokenFilter ;
57import me .zhengjie .modules .security .service .JwtUserDetailsService ;
68import org .springframework .beans .factory .annotation .Autowired ;
79import org .springframework .beans .factory .annotation .Value ;
10+ import org .springframework .context .ApplicationContext ;
811import org .springframework .context .annotation .Bean ;
912import org .springframework .context .annotation .Configuration ;
1013import org .springframework .http .HttpMethod ;
14+ import org .springframework .security .access .prepost .PreAuthorize ;
1115import org .springframework .security .authentication .AuthenticationManager ;
1216import org .springframework .security .config .annotation .authentication .builders .AuthenticationManagerBuilder ;
1317import org .springframework .security .config .annotation .method .configuration .EnableGlobalMethodSecurity ;
1923import org .springframework .security .crypto .bcrypt .BCryptPasswordEncoder ;
2024import org .springframework .security .crypto .password .PasswordEncoder ;
2125import org .springframework .security .web .authentication .UsernamePasswordAuthenticationFilter ;
26+ import org .springframework .web .method .HandlerMethod ;
27+ import org .springframework .web .servlet .mvc .method .RequestMappingInfo ;
28+ import org .springframework .web .servlet .mvc .method .annotation .RequestMappingHandlerMapping ;
29+
30+ import java .util .HashSet ;
31+ import java .util .Map ;
32+ import java .util .Set ;
2233
2334@ Configuration
2435@ EnableWebSecurity
@@ -29,16 +40,19 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
2940
3041 private final JwtUserDetailsService jwtUserDetailsService ;
3142
43+ private final ApplicationContext applicationContext ;
44+
3245 // 自定义基于JWT的安全过滤器
3346 private final JwtAuthorizationTokenFilter authenticationTokenFilter ;
3447
3548 @ Value ("${jwt.header}" )
3649 private String tokenHeader ;
3750
38- public SecurityConfig (JwtAuthenticationEntryPoint unauthorizedHandler , JwtUserDetailsService jwtUserDetailsService , JwtAuthorizationTokenFilter authenticationTokenFilter ) {
51+ public SecurityConfig (JwtAuthenticationEntryPoint unauthorizedHandler , JwtUserDetailsService jwtUserDetailsService , JwtAuthorizationTokenFilter authenticationTokenFilter , ApplicationContext applicationContext ) {
3952 this .unauthorizedHandler = unauthorizedHandler ;
4053 this .jwtUserDetailsService = jwtUserDetailsService ;
4154 this .authenticationTokenFilter = authenticationTokenFilter ;
55+ this .applicationContext = applicationContext ;
4256 }
4357
4458 @ Autowired
@@ -67,18 +81,26 @@ public AuthenticationManager authenticationManagerBean() throws Exception {
6781
6882 @ Override
6983 protected void configure (HttpSecurity httpSecurity ) throws Exception {
70-
84+ // 搜寻 匿名标记 url: PreAuthorize("hasAnyRole('anonymous')") 和 PreAuthorize("@el.check('anonymous')") 和 AnonymousAccess
85+ Map <RequestMappingInfo , HandlerMethod > handlerMethodMap = applicationContext .getBean (RequestMappingHandlerMapping .class ).getHandlerMethods ();
86+ Set <String > anonymousUrls = new HashSet <>();
87+ for (Map .Entry <RequestMappingInfo , HandlerMethod > infoEntry : handlerMethodMap .entrySet ()) {
88+ HandlerMethod handlerMethod = infoEntry .getValue ();
89+ AnonymousAccess anonymousAccess = handlerMethod .getMethodAnnotation (AnonymousAccess .class );
90+ PreAuthorize preAuthorize = handlerMethod .getMethodAnnotation (PreAuthorize .class );
91+ if (null != preAuthorize && preAuthorize .value ().contains ("anonymous" )) {
92+ anonymousUrls .addAll (infoEntry .getKey ().getPatternsCondition ().getPatterns ());
93+ } else if (null != anonymousAccess && null == preAuthorize ) {
94+ anonymousUrls .addAll (infoEntry .getKey ().getPatternsCondition ().getPatterns ());
95+ }
96+ }
7197 httpSecurity
72-
7398 // 禁用 CSRF
7499 .csrf ().disable ()
75-
76100 // 授权异常
77101 .exceptionHandling ().authenticationEntryPoint (unauthorizedHandler ).and ()
78-
79102 // 不创建会话
80103 .sessionManagement ().sessionCreationPolicy (SessionCreationPolicy .STATELESS ).and ()
81-
82104 // 过滤请求
83105 .authorizeRequests ()
84106 .antMatchers (
@@ -88,31 +110,20 @@ protected void configure(HttpSecurity httpSecurity) throws Exception {
88110 "/**/*.css" ,
89111 "/**/*.js"
90112 ).anonymous ()
91-
92- .antMatchers (HttpMethod .POST ,"/auth/login" ).permitAll ()
93- .antMatchers (HttpMethod .DELETE ,"/auth/logout" ).permitAll ()
94- .antMatchers (HttpMethod .GET ,"/auth/code" ).permitAll ()
95- // 支付宝回调
96- .antMatchers ("/api/aliPay/return" ).permitAll ()
97- .antMatchers ("/api/aliPay/notify" ).permitAll ()
98-
99113 // swagger start
100114 .antMatchers ("/swagger-ui.html" ).permitAll ()
101115 .antMatchers ("/swagger-resources/**" ).permitAll ()
102116 .antMatchers ("/webjars/**" ).permitAll ()
103117 .antMatchers ("/*/api-docs" ).permitAll ()
104118 // swagger end
105-
106- // 接口限流测试
107- .antMatchers ("/test/**" ).permitAll ()
108119 // 文件
109120 .antMatchers ("/avatar/**" ).permitAll ()
110121 .antMatchers ("/file/**" ).permitAll ()
111-
112122 // 放行OPTIONS请求
113123 .antMatchers (HttpMethod .OPTIONS , "/**" ).permitAll ()
114-
115124 .antMatchers ("/druid/**" ).permitAll ()
125+ // 自定义匿名访问所有url放行 : 允许 匿名和带权限以及登录用户访问
126+ .antMatchers (anonymousUrls .toArray (new String [0 ])).permitAll ()
116127 // 所有请求都需要认证
117128 .anyRequest ().authenticated ()
118129 // 防止iframe 造成跨域
0 commit comments