package com.moral.security.config; import com.fasterxml.jackson.databind.ObjectMapper; import com.moral.common.util.ResourceUtil; import com.moral.security.CustomCorsFilter; import com.moral.security.RestAuthenticationEntryPoint; import com.moral.security.auth.login.LoginAuthenticationProvider; import com.moral.security.auth.login.LoginProcessingFilter; import com.moral.security.auth.jwt.JwtAuthenticationProvider; import com.moral.security.auth.jwt.JwtTokenAuthenticationProcessingFilter; import com.moral.security.auth.jwt.SkipPathRequestMatcher; import com.moral.security.auth.jwt.extractor.TokenExtractor; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; 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.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * WebSecurityConfig * * @author vladimir.stankovic * * Aug 3, 2016 */ @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { public static final String AUTHENTICATION_HEADER_NAME = "X-Authorization"; public static final String REFRESH_TOKEN_HEADER_NAME = "X-Refrsh-Token"; public static final String AUTHENTICATION_PARAM_NAME = "_token"; public static final String AUTHENTICATION_URL = "/auth/login"; public static final String REFRESH_TOKEN_URL = "/auth/token"; public static final String API_ROOT_URL = "/**/*"; @Autowired private RestAuthenticationEntryPoint authenticationEntryPoint; @Autowired private AuthenticationSuccessHandler successHandler; @Autowired private AuthenticationFailureHandler failureHandler; @Autowired private LoginAuthenticationProvider ajaxAuthenticationProvider; @Autowired private JwtAuthenticationProvider jwtAuthenticationProvider; @Autowired private TokenExtractor tokenExtractor; @Autowired private AuthenticationManager authenticationManager; @Autowired private ObjectMapper objectMapper; protected LoginProcessingFilter buildLoginProcessingFilter(String loginEntryPoint) throws Exception { LoginProcessingFilter filter = new LoginProcessingFilter(loginEntryPoint, successHandler, failureHandler, objectMapper); filter.setAuthenticationManager(this.authenticationManager); return filter; } protected JwtTokenAuthenticationProcessingFilter buildJwtTokenAuthenticationProcessingFilter(List pathsToSkip, String pattern) throws Exception { SkipPathRequestMatcher matcher = new SkipPathRequestMatcher(pathsToSkip, pattern); JwtTokenAuthenticationProcessingFilter filter = new JwtTokenAuthenticationProcessingFilter(failureHandler, tokenExtractor, matcher); filter.setAuthenticationManager(this.authenticationManager); return filter; } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override protected void configure(AuthenticationManagerBuilder auth) { auth.authenticationProvider(ajaxAuthenticationProvider); auth.authenticationProvider(jwtAuthenticationProvider); } @Override protected void configure(HttpSecurity http) throws Exception { List permitAllEndpointList = new ArrayList<>(Arrays.asList( AUTHENTICATION_URL, REFRESH_TOKEN_URL )); // 添加不过滤的url String noFilters = ResourceUtil.getValue("noFilters"); if(!StringUtils.isBlank(noFilters)){ String[] noFilterArray = noFilters.split(","); if(!ArrayUtils.isEmpty(noFilterArray)){ permitAllEndpointList.addAll(Arrays.asList(noFilterArray)); } } http .csrf().disable() // We don't need CSRF for JWT based authentication .exceptionHandling() .authenticationEntryPoint(this.authenticationEntryPoint) .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() .antMatchers(permitAllEndpointList.toArray(new String[permitAllEndpointList.size()])) .permitAll() .and() .headers().frameOptions().disable() .and() .authorizeRequests() .antMatchers(API_ROOT_URL).authenticated() // Protected API End-points .and() .addFilterBefore(new CustomCorsFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(buildLoginProcessingFilter(AUTHENTICATION_URL), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(buildJwtTokenAuthenticationProcessingFilter(permitAllEndpointList, API_ROOT_URL), UsernamePasswordAuthenticationFilter.class); } }