package com.kidgrow.oauth2.config;
|
|
import com.kidgrow.common.constant.SecurityConstants;
|
//import com.kidgrow.oauth2.handler.InMemoryAuthenticationProvider;
|
import com.kidgrow.oauth2.mobile.MobileAuthenticationSecurityConfig;
|
import com.kidgrow.oauth2.openid.OpenIdAuthenticationSecurityConfig;
|
import com.kidgrow.common.config.DefaultPasswordConfig;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Import;
|
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.authentication.builders.AuthenticationManagerBuilder;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
|
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
|
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
import org.springframework.security.web.header.HeaderWriterFilter;
|
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
|
|
import javax.annotation.Resource;
|
import java.util.Arrays;
|
|
|
/**
|
* 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
|
*
|
* @Description: * spring security配置
|
* * 在WebSecurityConfigurerAdapter不拦截oauth要开放的资源<br>
|
* @Project: <br>
|
* @CreateDate: Created in 2020/2/20 09:19 <br>
|
* @Author: <a href="4345453@kidgrow.com">liuke</a>
|
*/
|
@Configuration
|
@Import(DefaultPasswordConfig.class)
|
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|
@Autowired
|
private AuthenticationSuccessHandler authenticationSuccessHandler;
|
@Autowired
|
private AuthenticationFailureHandler authenticationFailureHandler;
|
|
@Autowired(required = false)
|
private AuthenticationEntryPoint authenticationEntryPoint;
|
|
@Resource
|
private UserDetailsService userDetailsService;
|
|
@Autowired
|
private PasswordEncoder passwordEncoder;
|
|
@Resource
|
private LogoutHandler oauthLogoutHandler;
|
|
@Autowired
|
private ValidateCodeSecurityConfig validateCodeSecurityConfig;
|
|
@Autowired
|
private OpenIdAuthenticationSecurityConfig openIdAuthenticationSecurityConfig;
|
|
@Autowired
|
private MobileAuthenticationSecurityConfig mobileAuthenticationSecurityConfig;
|
|
// @Autowired
|
// InMemoryAuthenticationProvider inMemoryAuthenticationProvider;
|
|
/**
|
* 这一步的配置是必不可少的,否则SpringBoot会自动配置一个AuthenticationManager,覆盖掉内存中的用户
|
* @return 认证管理对象
|
*/
|
@Bean
|
@Override
|
public AuthenticationManager authenticationManagerBean() throws Exception {
|
return super.authenticationManagerBean();
|
}
|
// @Bean
|
// @Override
|
// public AuthenticationManager authenticationManagerBean() throws Exception {
|
// // 认证管理器中只提供我需要的两个第一个是自定义认证,第二个是数据库认证,需要经过两层认证才能通过,默认的
|
//
|
// // 构造函数不提供自定义认证Provider,那么默认提供DaoAuthenticationProvider
|
//
|
// ProviderManager authenticationManager = new ProviderManager(Arrays.asList(inMemoryAuthenticationProvider, daoAuthenticationProvider()));
|
//
|
// // 不擦除认证密码,擦除会导致TokenBasedRememberMeServices因为找不到Credentials再调用UserDetailsService而抛出UsernameNotFoundException
|
//
|
// authenticationManager.setEraseCredentialsAfterAuthentication(false);
|
//
|
// return authenticationManager;
|
// }
|
|
|
@Override
|
protected void configure(HttpSecurity http) throws Exception {
|
http.authorizeRequests()
|
.anyRequest()
|
//授权服务器关闭basic认证
|
.permitAll()
|
.and()
|
.formLogin()
|
.loginPage(SecurityConstants.LOGIN_PAGE)
|
.loginProcessingUrl(SecurityConstants.OAUTH_LOGIN_PRO_URL)
|
.successHandler(authenticationSuccessHandler)
|
.failureHandler(authenticationFailureHandler)
|
.and()
|
.logout()
|
.logoutUrl(SecurityConstants.LOGOUT_URL)
|
.logoutSuccessUrl(SecurityConstants.LOGIN_PAGE)
|
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
|
.addLogoutHandler(oauthLogoutHandler)
|
.clearAuthentication(true)
|
.and()
|
.apply(validateCodeSecurityConfig)
|
.and()
|
.apply(openIdAuthenticationSecurityConfig)
|
.and()
|
.apply(mobileAuthenticationSecurityConfig)
|
.and()
|
.csrf().disable()
|
// 解决不允许显示在iframe的问题
|
.headers().frameOptions().disable().cacheControl();
|
|
// 基于密码 等模式可以无session,不支持授权码模式
|
if (authenticationEntryPoint != null) {
|
http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
|
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
} else {
|
// 授权码模式单独处理,需要session的支持,此模式可以支持所有oauth2的认证
|
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
|
}
|
}
|
|
/**
|
* 全局用户信息
|
*/
|
@Autowired
|
public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
|
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
|
}
|
}
|