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 {@Resourceprivate JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;@Resourceprivate SecurityUserServiceImpl userDetailsService;@Resourceprivate WechatAppUserServiceImpl wechatAppUserService;/*** 認證失敗處理器*/@Resourceprivate AuthenticationEntryPointImpl authenticationEntryPoint;@Resourceprivate AccessDeniedHandlerImpl accessDeniedHandler;@Resourceprivate RequestMatcher[] requestMatchers;@Beanpublic 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 filterhttp.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);// 認證失敗處理類http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).accessDeniedHandler(accessDeniedHandler);// SpringSecurity設置允許跨域http.cors().disable();return http.build();}/*** 靜態文件放行*/@Beanpublic WebSecurityCustomizer webSecurityCustomizer() {return (web) -> web.ignoring().antMatchers("/staic/**", "/web/**");}@Beanpublic PasswordEncoder passwordEncoder() {return new CustomPasswordService();}/*** 設置默認認證提供 用戶名密碼登錄*/@Beanpublic DaoAuthenticationProvider daoAuthenticationProvider() {final DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();authenticationProvider.setUserDetailsService(userDetailsService);authenticationProvider.setPasswordEncoder(passwordEncoder());return authenticationProvider;}/*** 設置小程序的登錄驗證方式 openid驗證登錄 沒有密碼** @return*/@Beanpublic 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*/@Beanpublic 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;@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {// 關閉csrf 因為不使用sessionhttp.csrf(csrf -> csrf.disable());// 禁用HTTP響應標頭http.headers(headers -> headers.frameOptions(frameOptionsConfig -> frameOptionsConfig.disable()));//不通過Session獲取SecurityContext 基于token,所以不需要sessionhttp.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 filterhttp.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);// 認證失敗處理類http.exceptionHandling(exceptionHandlingConfigurer -> exceptionHandlingConfigurer.authenticationEntryPoint(authenticationEntryPoint).accessDeniedHandler(accessDeniedHandler));// SpringSecurity設置允許跨域http.cors(cors -> cors.disable());return http.build();}/*** 靜態文件放行*/@Beanpublic WebSecurityCustomizer webSecurityCustomizer() {return (web) -> web.ignoring().requestMatchers("/staic/**", "/web/**");}@Beanpublic PasswordEncoder passwordEncoder() {return new CustomPasswordService();}/*** 設置默認認證提供 用戶名密碼登錄*/@Beanpublic DaoAuthenticationProvider daoAuthenticationProvider() {final DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();authenticationProvider.setUserDetailsService(userDetailsService);authenticationProvider.setPasswordEncoder(passwordEncoder());return authenticationProvider;}/*** 設置小程序的登錄驗證方式 openid驗證登錄 沒有密碼** @return*/@Beanpublic 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*/@Beanpublic AuthenticationManager authenticationManager() throws Exception {ProviderManager authenticationManager = new ProviderManager(Arrays.asList(daoAuthenticationProvider(), daoWechatAppUserAuthenticationProvider()));return authenticationManager;}}