WebSecurityConfig.java 4.36 KB
package com.bsth.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.session.HttpSessionEventPublisher;

import com.bsth.common.Constants;
import com.bsth.security.filter.LoginInterceptor;
import com.bsth.security.handler.CustomLogoutHandler;
import com.bsth.security.handler.LoginSuccessHandler;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	UserDetailServiceImpl customUserDetailService;

	@Autowired
	CustomAccessDecisionManager customAccessDecisionManager;

	@Autowired
	SecurityMetadataSourceService securityMetadataSourceService;

	
	@Override
	public void configure(WebSecurity web) throws Exception {
		// 白名单
		web.ignoring().antMatchers(Constants.LOGIN_PAGE, Constants.ASSETS_URL, Constants.FAVICON_URL,
				Constants.METRONIC_URL, Constants.LOGIN_FAILURE, Constants.UPSTREAM_URL, Constants.XD_CHILD_PAGES, Constants.XD_TEMPS);
	}

	@Override
	protected void configure(AuthenticationManagerBuilder auth)
			throws Exception {
		auth.userDetailsService(customUserDetailService).passwordEncoder(
				new BCryptPasswordEncoder(4));
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests().antMatchers("/").permitAll().anyRequest()
				.authenticated().and()
				.formLogin()
				 //指定登录页
				.loginPage(Constants.LOGIN_PAGE)
				.loginProcessingUrl(Constants.LOGIN).permitAll()
				 //登录失败跳转的链接
				.failureUrl(Constants.LOGIN_PAGE + "?error=true")
				 //登录成功后处理
				.successHandler(loginSuccessHandler())
				 //登出
				.and().logout()
				.addLogoutHandler(logoutHandler())
				 //禁用CXRF
				.and().csrf().disable() 
				 //禁用匿名用户功能
				.anonymous().disable();

		// 同时只保持一个回话
		http.sessionManagement().maximumSessions(1)
				.expiredUrl(Constants.LOGIN_PAGE + "?error=true")
				.maxSessionsPreventsLogin(false)//让之前的登录过期
				.sessionRegistry(sessionRegistry());
		
		http.addFilterBefore(new LoginInterceptor(), FilterSecurityInterceptor.class);
		http.addFilter(filterSecurityInterceptor());
	}

	private FilterSecurityInterceptor filterSecurityInterceptor()
			throws Exception {
		FilterSecurityInterceptor filterSecurityInterceptor = new FilterSecurityInterceptor();
		filterSecurityInterceptor
				.setAccessDecisionManager(customAccessDecisionManager);
		filterSecurityInterceptor
				.setSecurityMetadataSource(securityMetadataSourceService);
		filterSecurityInterceptor
				.setAuthenticationManager(authenticationManager());
		return filterSecurityInterceptor;
	}
	
	@Bean
	public LoginSuccessHandler loginSuccessHandler(){
		return new LoginSuccessHandler();
	}
	
	@Bean
	public LogoutHandler logoutHandler(){
		return new CustomLogoutHandler();
	}

	@Bean
	public SessionRegistry sessionRegistry() {
		SessionRegistry sessionRegistry = new SessionRegistryImpl();
		return sessionRegistry;
	}
	
	@Bean
	public static ServletListenerRegistrationBean<HttpSessionEventPublisher> httpSessionEventPublisher() {
		return new ServletListenerRegistrationBean<HttpSessionEventPublisher>(
				new HttpSessionEventPublisher());
	}
}