| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- /*
- * Copyright 2019-2020 Zheng Jie
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package me.zhengjie.security.config;
- import lombok.RequiredArgsConstructor;
- import me.zhengjie.annotation.AnonymousAccess;
- import me.zhengjie.security.config.bean.SecurityProperties;
- import me.zhengjie.security.security.TokenConfigurer;
- import me.zhengjie.security.security.TokenFilter;
- import me.zhengjie.security.security.TokenProvider;
- import me.zhengjie.security.service.OnlineUserService;
- import me.zhengjie.utils.enums.RequestMethodEnum;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.http.HttpMethod;
- 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.configuration.EnableWebSecurity;
- import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
- import org.springframework.security.config.core.GrantedAuthorityDefaults;
- import org.springframework.security.config.http.SessionCreationPolicy;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- import org.springframework.security.crypto.password.PasswordEncoder;
- import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.filter.CorsFilter;
- import org.springframework.web.method.HandlerMethod;
- import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
- import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
- import java.util.*;
- /**
- * @author Zheng Jie
- */
- @Configuration
- @EnableWebSecurity
- @RequiredArgsConstructor
- @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
- public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
- private final TokenProvider tokenProvider;
- private final CorsFilter corsFilter;
- // private final JwtAuthenticationEntryPoint authenticationErrorHandler;
- // private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
- private final ApplicationContext applicationContext;
- private final SecurityProperties properties;
- private final OnlineUserService onlineUserService;
- @Bean
- GrantedAuthorityDefaults grantedAuthorityDefaults() {
- // 去除 ROLE_ 前缀
- return new GrantedAuthorityDefaults("");
- }
- @Bean
- public PasswordEncoder passwordEncoder() {
- // 密码加密方式
- return new BCryptPasswordEncoder();
- }
- @Override
- protected void configure(HttpSecurity httpSecurity) throws Exception {
- // 搜寻匿名标记 url: @AnonymousAccess
- RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping");
- Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods();
- // 获取匿名标记
- Map<String, Set<String>> anonymousUrls = getAnonymousUrl(handlerMethodMap);
- httpSecurity
- // 禁用 CSRF
- .csrf().disable()
- .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
- // 授权异常
- .exceptionHandling()
- // .authenticationEntryPoint(authenticationErrorHandler)
- // .accessDeniedHandler(jwtAccessDeniedHandler)
- // 防止iframe 造成跨域
- .and()
- .headers()
- .frameOptions()
- .disable()
- // 不创建会话
- .and()
- .sessionManagement()
- .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
- .and()
- .authorizeRequests()
- // 静态资源等等
- .antMatchers(
- HttpMethod.GET,
- "/*.html",
- "/**/*.html",
- "/**/*.png",
- "/**/*.css",
- "/**/*.ico",
- "/**/*.js",
- "/webSocket/**",
- "/appSocketServer/**",
- "/socket.io/**"
- // "/tencentpush",
- // "/apppush"
- ).permitAll()
- // swagger 文档
- .antMatchers("/swagger-ui.html").permitAll()
- .antMatchers("/swagger-resources/**").permitAll()
- .antMatchers("/app/**").permitAll()
- .antMatchers("/api/bank-app/**").permitAll()
- .antMatchers("/minipro/**").permitAll()
- .antMatchers("/image/**").permitAll()
- .antMatchers("/webjars/**").permitAll()
- .antMatchers("/*/api-docs").permitAll()
- // 文件
- .antMatchers("/avatar/**").permitAll()
- .antMatchers("/file/**").permitAll()
- .antMatchers("/static/**").permitAll()
- // 阿里巴巴 druid
- .antMatchers("/druid/**").permitAll()
- // 放行OPTIONS请求
- .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
- // 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型
- // GET
- .antMatchers(HttpMethod.GET, anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0])).permitAll()
- // POST
- .antMatchers(HttpMethod.POST, anonymousUrls.get(RequestMethodEnum.POST.getType()).toArray(new String[0])).permitAll()
- // PUT
- .antMatchers(HttpMethod.PUT, anonymousUrls.get(RequestMethodEnum.PUT.getType()).toArray(new String[0])).permitAll()
- // PATCH
- .antMatchers(HttpMethod.PATCH, anonymousUrls.get(RequestMethodEnum.PATCH.getType()).toArray(new String[0])).permitAll()
- // DELETE
- .antMatchers(HttpMethod.DELETE, anonymousUrls.get(RequestMethodEnum.DELETE.getType()).toArray(new String[0])).permitAll()
- // 所有类型的接口都放行
- .antMatchers(anonymousUrls.get(RequestMethodEnum.ALL.getType()).toArray(new String[0])).permitAll()
- // 所有请求都需要认证
- .anyRequest().authenticated()
- .and().apply(securityConfigurerAdapter());
- //设置所有的不需要权限访问的
- TokenFilter.setAnonymousUrl(anonymousUrls);
- System.out.println(anonymousUrls);
- }
- private TokenConfigurer securityConfigurerAdapter() {
- return new TokenConfigurer(tokenProvider, properties, onlineUserService);
- }
- private Map<String, Set<String>> getAnonymousUrl(Map<RequestMappingInfo, HandlerMethod> handlerMethodMap) {
- Map<String, Set<String>> anonymousUrls = new HashMap<>(8);
- Set<String> get = new HashSet<>();
- Set<String> post = new HashSet<>();
- Set<String> put = new HashSet<>();
- Set<String> patch = new HashSet<>();
- Set<String> delete = new HashSet<>();
- Set<String> all = new HashSet<>();
- for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethodMap.entrySet()) {
- HandlerMethod handlerMethod = infoEntry.getValue();
- AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class);
- if (null != anonymousAccess) {
- List<RequestMethod> requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods());
- RequestMethodEnum request = RequestMethodEnum.find(requestMethods.size() == 0 ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name());
- switch (Objects.requireNonNull(request)) {
- case GET:
- get.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
- break;
- case POST:
- post.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
- break;
- case PUT:
- put.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
- break;
- case PATCH:
- patch.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
- break;
- case DELETE:
- delete.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
- break;
- default:
- all.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
- break;
- }
- }
- }
- anonymousUrls.put(RequestMethodEnum.GET.getType(), get);
- anonymousUrls.put(RequestMethodEnum.POST.getType(), post);
- anonymousUrls.put(RequestMethodEnum.PUT.getType(), put);
- anonymousUrls.put(RequestMethodEnum.PATCH.getType(), patch);
- anonymousUrls.put(RequestMethodEnum.DELETE.getType(), delete);
- anonymousUrls.put(RequestMethodEnum.ALL.getType(), all);
- return anonymousUrls;
- }
- }
|