springsecurity5和springsecurity6如何要实现多种登录方式,自定义登录方式都是一样的操作步骤,主要有四个步骤。
一、自定义登录用户实体实现springsecurity中的UserDetails接口
二、自定义登录用户实现类实现springsecurity中的UserDetailsService接口
三、自定义登录用户authentic验证器继承springsecurity中的AbstractAuthenticationToken抽象类
四、自定义登录用户provider验证管理器实现springsecurity中的AuthenticationProvider接口
一、springsecurity5.7.x配置
package com.school.information.config;
import com.school.information.core.security.filter.JwtAuthenticationTokenFilter;
import com.school.information.core.security.handler.AccessDeniedHandlerImpl;
import com.school.information.core.security.handler.AuthenticationEntryPointImpl;
import com.school.information.core.security.provider.WechatAppUserAuthenticationProvider;
import com.school.information.core.service.CustomPasswordService;
import com.school.information.core.service.SecurityUserServiceImpl;
import com.school.information.core.service.WechatAppUserServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
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.WebSecurityCustomizer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.RequestMatcher;
import javax.annotation.Resource;
import java.util.Arrays;
/*
* SecuritConfig配置类
*/
@EnableWebSecurity
@EnableMethodSecurity // 开启注解授权功能
public class SecurityConfig {
@Resource
private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
@Resource
private SecurityUserServiceImpl userDetailsService;
@Resource
private WechatAppUserServiceImpl wechatAppUserService;
/**
* 认证失败处理器
*/
@Resource
private AuthenticationEntryPointImpl authenticationEntryPoint;
@Resource
private AccessDeniedHandlerImpl accessDeniedHandler;
@Resource
private RequestMatcher[] requestMatchers;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// 关闭csrf 因为不使用session
.csrf().disable()
// 禁用HTTP响应标头
.headers().frameOptions().disable()
.and()
//不通过Session获取SecurityContext 基于token,所以不需要session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
// 过滤请求
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(requestMatchers).permitAll()
.anyRequest().authenticated());
//对于登录login 注册register 验证码captchaImage 无需拦截 直接访问
// .antMatchers("/", "/token/captcha").permitAll()
// // 静态资源,可匿名访问
// .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
// .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
// 除上面外的所有请求全部需要鉴权认证
// .anyRequest().authenticated();
// 添加JWT filter
http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
// 认证失败处理类
http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).accessDeniedHandler(accessDeniedHandler);
// SpringSecurity设置允许跨域
http.cors().disable();
return http.build();
}
/**
* 静态文件放行
*/
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/staic/**", "/web/**");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new CustomPasswordService();
}
/**
* 设置默认认证提供 用户名密码登录
*/
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
final DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
/**
* 设置小程序的登录验证方式 openid验证登录 没有密码
*
* @return
*/
@Bean
public WechatAppUserAuthenticationProvider daoWechatAppUserAuthenticationProvider() {
final WechatAppUserAuthenticationProvider wechatAppUserAuthenticationProvider = new WechatAppUserAuthenticationProvider();
wechatAppUserAuthenticationProvider.setUserDetailsService(wechatAppUserService);
return wechatAppUserAuthenticationProvider;
}
// 获取AuthenticationManager(认证管理器),登录时认证使用。 默认UsernamePasswordAuthenticationToken
// @Bean
// public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
// return authenticationConfiguration.getAuthenticationManager();
// }
/**
* 对于默认的认证管理器 UsernamePasswordAuthenticationToken 直接使用上方的注释掉的代码即可
* 如果项目中需要多个不同的认证管理器,需要使用下方的代码,将不同的认证管理器交由providerManager去管理
*
* @return
* @throws Exception
*/
@Bean
public AuthenticationManager authenticationManager() throws Exception {
ProviderManager authenticationManager = new ProviderManager(Arrays.asList(daoAuthenticationProvider(), daoWechatAppUserAuthenticationProvider()));
return authenticationManager;
}
}
二、springsecurity6.x配置文件
package com.school.information.config;
import com.school.information.core.security.filter.JwtAuthenticationTokenFilter;
import com.school.information.core.security.handler.AccessDeniedHandlerImpl;
import com.school.information.core.security.handler.AuthenticationEntryPointImpl;
import com.school.information.core.security.provider.WechatAppUserAuthenticationProvider;
import com.school.information.core.service.CustomPasswordService;
import com.school.information.core.service.SecurityUserServiceImpl;
import com.school.information.core.service.WechatAppUserServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
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.WebSecurityCustomizer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.RequestMatcher;
import java.util.Arrays;
/*
* SecuritConfig配置类
*/
@Configuration
@EnableWebSecurity
@EnableMethodSecurity // 开启注解授权功能
@RequiredArgsConstructor
public class SecurityConfig {
private final JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
private final SecurityUserServiceImpl userDetailsService;
private final WechatAppUserServiceImpl wechatAppUserService;
/**
* 认证失败处理器
*/
private final AuthenticationEntryPointImpl authenticationEntryPoint;
private final AccessDeniedHandlerImpl accessDeniedHandler;
private final RequestMatcher[] requestMatchers;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// 关闭csrf 因为不使用session
http.csrf(csrf -> csrf.disable());
// 禁用HTTP响应标头
http.headers(headers -> headers.frameOptions(frameOptionsConfig -> frameOptionsConfig.disable()));
//不通过Session获取SecurityContext 基于token,所以不需要session
http.sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
// 过滤请求
http.authorizeHttpRequests(authorize -> authorize
.requestMatchers(requestMatchers).permitAll()
.anyRequest().authenticated());
//对于登录login 注册register 验证码captchaImage 无需拦截 直接访问
// .antMatchers("/", "/token/captcha").permitAll()
// // 静态资源,可匿名访问
// .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
// .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
// 除上面外的所有请求全部需要鉴权认证
// .anyRequest().authenticated();
// 添加JWT filter
http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
// 认证失败处理类
http.exceptionHandling(
exceptionHandlingConfigurer -> exceptionHandlingConfigurer
.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler)
);
// SpringSecurity设置允许跨域
http.cors(cors -> cors.disable());
return http.build();
}
/**
* 静态文件放行
*/
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().requestMatchers("/staic/**", "/web/**");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new CustomPasswordService();
}
/**
* 设置默认认证提供 用户名密码登录
*/
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
final DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
/**
* 设置小程序的登录验证方式 openid验证登录 没有密码
*
* @return
*/
@Bean
public WechatAppUserAuthenticationProvider daoWechatAppUserAuthenticationProvider() {
final WechatAppUserAuthenticationProvider wechatAppUserAuthenticationProvider = new WechatAppUserAuthenticationProvider();
wechatAppUserAuthenticationProvider.setUserDetailsService(wechatAppUserService);
return wechatAppUserAuthenticationProvider;
}
// 获取AuthenticationManager(认证管理器),登录时认证使用。 默认UsernamePasswordAuthenticationToken
// @Bean
// public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
// return authenticationConfiguration.getAuthenticationManager();
// }
/**
* 如果项目中需要多个不同的认证管理器,需要使用下方的代码,将不同的认证管理器交由providerManager去管理
*
* @return
* @throws Exception
*/
@Bean
public AuthenticationManager authenticationManager() throws Exception {
ProviderManager authenticationManager = new ProviderManager(
Arrays.asList(daoAuthenticationProvider(), daoWechatAppUserAuthenticationProvider())
);
return authenticationManager;
}
}