game-api/ff-base/src/main/java/com/ff/base/config/SecurityConfig.java

176 lines
7.6 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.ff.base.config;
import com.ff.base.config.properties.PermitAllUrlProperties;
import com.ff.base.security.encode.CustomMd5PasswordEncoder;
import com.ff.base.security.filter.JwtAuthenticationTokenFilter;
import com.ff.base.security.handle.AuthenticationEntryPointImpl;
import com.ff.base.security.handle.LogoutSuccessHandlerImpl;
import com.ff.base.security.provider.MyDaoAuthenticationProvider;
import com.ff.base.web.service.AgentDetailsServiceImpl;
import com.ff.base.web.service.TenantDetailsServiceImpl;
import com.ff.base.web.service.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.web.filter.CorsFilter;
import java.util.ArrayList;
import java.util.List;
/**
* spring security配置
*
* @author ff
*/
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Configuration
public class SecurityConfig {
/**
* 后台自定义用户认证逻辑
*/
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private TenantDetailsServiceImpl tenantDetailsService;
@Autowired
private AgentDetailsServiceImpl agentDetailsService;
/**
* 认证失败处理类
*/
@Autowired
private AuthenticationEntryPointImpl unauthorizedHandler;
/**
* 退出处理类
*/
@Autowired
private LogoutSuccessHandlerImpl logoutSuccessHandler;
/**
* token认证过滤器
*/
@Autowired
private JwtAuthenticationTokenFilter authenticationTokenFilter;
/**
* 跨域过滤器
*/
@Autowired
private CorsFilter corsFilter;
/**
* 允许匿名访问的地址
*/
@Autowired
private PermitAllUrlProperties permitAllUrl;
/**
* 身份验证实现
*/
@Bean
public AuthenticationManager authenticationManager() {
// 后台、会员两种验证方式实现类
List<UserDetailsService> userDetailsServices = new ArrayList<>();
userDetailsServices.add(userDetailsService);
userDetailsServices.add(tenantDetailsService);
userDetailsServices.add(agentDetailsService);
List<AuthenticationProvider> providers = new ArrayList<>();
MyDaoAuthenticationProvider adminDaoAuthenticationProvider = new MyDaoAuthenticationProvider();
adminDaoAuthenticationProvider.setUserDetailsService(userDetailsService); // or userDetailsService
adminDaoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder());
adminDaoAuthenticationProvider.setUserDetailsServices(userDetailsServices);
providers.add(adminDaoAuthenticationProvider);
MyDaoAuthenticationProvider adminDaoAuthenticationProvider1 = new MyDaoAuthenticationProvider();
adminDaoAuthenticationProvider1.setUserDetailsService(tenantDetailsService);
adminDaoAuthenticationProvider1.setPasswordEncoder(bCryptPasswordEncoder());
adminDaoAuthenticationProvider1.setUserDetailsServices(userDetailsServices);
MyDaoAuthenticationProvider adminDaoAuthenticationProvider2 = new MyDaoAuthenticationProvider();
adminDaoAuthenticationProvider2.setUserDetailsService(agentDetailsService);
adminDaoAuthenticationProvider2.setPasswordEncoder(bCryptPasswordEncoder());
adminDaoAuthenticationProvider2.setUserDetailsServices(userDetailsServices);
return new ProviderManager(providers);
}
/**
* anyRequest | 匹配所有请求路径
* access | SpringEl表达式结果为true时可以访问
* anonymous | 匿名可以访问
* denyAll | 用户不能访问
* fullyAuthenticated | 用户完全认证可以访问非remember-me下自动登录
* hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问
* hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问
* hasAuthority | 如果有参数,参数表示权限,则其权限可以访问
* hasIpAddress | 如果有参数参数表示IP地址如果用户IP和参数匹配则可以访问
* hasRole | 如果有参数,参数表示角色,则其角色可以访问
* permitAll | 用户可以任意访问
* rememberMe | 允许通过remember-me登录的用户访问
* authenticated | 用户登录后可访问
*/
@Bean
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
// CSRF禁用因为不使用session
.csrf(csrf -> csrf.disable())
// 禁用HTTP响应标头
.headers((headersCustomizer) -> {
headersCustomizer.cacheControl(cache -> cache.disable()).frameOptions(options -> options.sameOrigin());
})
// 认证失败处理类
.exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
// 基于token所以不需要session
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
// 注解标记允许匿名访问的url
.authorizeHttpRequests((requests) -> {
permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
requests.antMatchers("/api/**","/login", "/register","/ws", "/captchaImage").permitAll()
// 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated();
})
// 添加Logout filter
.logout(logout -> logout.logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler))
// 添加JWT filter
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
// 添加CORS filter
.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class)
.addFilterBefore(corsFilter, LogoutFilter.class)
.build();
}
/**
* 强散列哈希加密实现
*/
@Bean
public CustomMd5PasswordEncoder bCryptPasswordEncoder() {
return new CustomMd5PasswordEncoder();
}
}