是否可以拆分spring的SecurityConfig?
Posted
技术标签:
【中文标题】是否可以拆分spring的SecurityConfig?【英文标题】:Is it possible to split the SecurityConfig of spring? 【发布时间】:2018-05-02 16:04:36 【问题描述】:我有一个带有childA
和childB
的项目。
我想配置childA
中的childA
控制器和childB
中的childB
控制器的安全性。
到目前为止,我有以下SecurityConfig
:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
private CookieProperties cookieProperties;
@Autowired
private LdapUserDetailsManager userDetailsService;
@Autowired
private AuthenticationSuccessHandler authenticationSuccessHandler;
@Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
@Autowired
private AuthenticationFailureHandler authenticationFailureHandler;
@Autowired
private AccessDeniedHandler accessDeniedHandler;
@Autowired
private LogoutSuccessHandler logoutSuccessHandler;
@Autowired
private LdapProperties ldapProperties;
@Autowired
private Environment environment;
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
return super.authenticationManagerBean();
@Bean
public LdapDaoAuthenticationProvider ldapDaoAuthenticationProvider(LdapProperties ldapProperties)
LdapDaoAuthenticationProvider provider = new LdapDaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService);
provider.setLdapProperties(ldapProperties);
provider.setPasswordEncoder(passwordEncoder());
return provider;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.authenticationProvider(ldapDaoAuthenticationProvider(ldapProperties));
@Override
protected void configure(HttpSecurity http) throws Exception
http
.requestMatcher(
// how to move this in another file ?
new OrRequestMatcher(
new AntPathRequestMatcher(ChildAHttpPathStore.PATH_SOMETHING),
new AntPathRequestMatcher(ChildBHttpPathStore.PATH_SOMETHING),
)
)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.NEVER)
.and()
.csrf()
.csrfTokenRepository(corsCookieCsrfTokenRepository())
.and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, CoreHttpPathStore.PING).permitAll()
.anyRequest().hasAnyAuthority(
UserManagement.ROLE_AUTH_SERVICE
)
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler)
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.formLogin()
.loginProcessingUrl(CoreHttpPathStore.LOGIN)
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.permitAll()
.and()
.logout()
.logoutUrl(CoreHttpPathStore.LOGOUT)
.logoutSuccessUrl(CoreHttpPathStore.LOGIN_FROM_LOGOUT)
.logoutSuccessHandler(logoutSuccessHandler)
.permitAll()
.and()
.headers().cacheControl().disable();
@Bean(name = "userPasswordEncoder")
public LdapShaPasswordEncoder passwordEncoder()
return new LdapShaPasswordEncoder();
@Bean
public CookieSerializer cookieSerializer()
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
if (null != cookieProperties.getName()) serializer.setCookieName(cookieProperties.getName());
if (null != cookieProperties.getPath()) serializer.setCookiePath(cookieProperties.getPath());
if (null != cookieProperties.getHttpOnly()) serializer.setUseHttpOnlyCookie(cookieProperties.getHttpOnly());
if (null != cookieProperties.getMaxAge()) serializer.setCookieMaxAge(cookieProperties.getMaxAge());
if (null != cookieProperties.getSecure()) serializer.setUseSecureCookie(cookieProperties.getSecure());
if (null != cookieProperties.getDomain()) serializer.setDomainName(cookieProperties.getDomain());
return serializer;
@Bean
public CorsCookieCsrfTokenRepository corsCookieCsrfTokenRepository()
CorsCookieCsrfTokenRepository repository = new CorsCookieCsrfTokenRepository();
repository.setCookieHttpOnly(false);
repository.setHeaderName("X-XSRF-TOKEN");
repository.setCookiePath(cookieProperties.getPath());
repository.setCookieDomain(cookieProperties.getDomain());
repository.setCookieName("XSRF-TOKEN");
return repository;
是否可以拆分此配置?
【问题讨论】:
你可以在需要的地方单独使用@import导入 我只是用http.requestMatcher(/mypath)
编写配置方法,它会工作吗?之后的链条呢?
【参考方案1】:
如果您因为spring security docs 而需要编写Multiple HttpSecurity,最简单的方法是创建一个通用配置,其中包含一些用于配置HttpSecurity 的内部@Configuration 类
@EnableWebSecurity
public class MultiHttpSecurityConfig
@Bean
public UserDetailsService userDetailsService() throws Exception
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user").password("password").roles("USER").build());
manager.createUser(User.withUsername("admin").password("password").roles("USER","ADMIN").build());
return manager;
@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter
protected void configure(HttpSecurity http) throws Exception
http
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
@Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin();
【讨论】:
我在使用两个不同的项目,所以这个类需要在两个不同的文件中 你看起来像这样吗baeldung.com/spring-security-multiple-entry-points 这太复杂了。我只想能够在每个相应的包中声明匹配项,而不是将所有匹配项(使用 antMatcher 配置)存储在一个文件中。以上是关于是否可以拆分spring的SecurityConfig?的主要内容,如果未能解决你的问题,请参考以下文章
Spring Cloud与微服务学习总结(13)——云原生趋势下,微服务的拆分粒度如何把握?
Spring Cloud与微服务学习总结(13)——云原生趋势下,微服务的拆分粒度如何把握?