使用Spring安全性Javaconfig进行基本和基于表单的身份validation

我正在尝试为不同的url模式定义两种不同的安全配置,其中一种使用表单登录,另一种使用api的基本身份validation。

我正在寻找的解决方案类似于此处解释的解决方案http://meera-subbarao.blogspot.co.uk/2010/11/spring-security-combining-basic-and.html但我想这样做使用java配置。

提前致谢。

这是我目前的配置:

@Configuration @EnableWebSecurity public class AppSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserService userService; @Override protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userService); } @Override public void configure(WebSecurity web) throws Exception { // Ignore any request that starts with "/resources/". web.ignoring().antMatchers("/resources/**"); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeUrls().antMatchers("/", "/index", "/user/**", "/about").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and().formLogin() .loginUrl("/login") .failureUrl("/login-error") .loginProcessingUrl("/security_check") .usernameParameter("j_username").passwordParameter("j_password") .permitAll(); http.logout().logoutUrl("/logout"); http.rememberMe().rememberMeServices(rememberMeServices()).key("password"); } @Bean public RememberMeServices rememberMeServices() { TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices("password", userService); rememberMeServices.setCookieName("cookieName"); rememberMeServices.setParameter("rememberMe"); return rememberMeServices; } } 

我找到的解决方案是在第一个内部创建另一个扩展WebSecurityConfigurerAdapter的类,如https://github.com/spring-projects/spring-security-javaconfig/blob/master/samples-web.md#sample-multi -http-Web的配置

我的解决方案如下:

 @Configuration @EnableWebSecurity public class AppSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserService userService; @Override protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userService); } @Override public void configure(WebSecurity web) throws Exception { // Ignore any request that starts with "/resources/". web.ignoring().antMatchers("/resources/**"); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeUrls().antMatchers("/", "/index", "/user/**", "/about").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and().formLogin() .loginUrl("/login") .failureUrl("/login-error") .loginProcessingUrl("/security_check") .usernameParameter("j_username").passwordParameter("j_password") .permitAll(); http.logout().logoutUrl("/logout"); http.rememberMe().rememberMeServices(rememberMeServices()).key("password"); } @Bean public RememberMeServices rememberMeServices() { TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices("password", userService); rememberMeServices.setCookieName("cookieName"); rememberMeServices.setParameter("rememberMe"); return rememberMeServices; } @Configuration @Order(1) public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { @Override protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("api").password("pass").roles("API"); } protected void configure(HttpSecurity http) throws Exception { http.authorizeUrls() .antMatchers("/api/**").hasRole("API") .and() .httpBasic(); } } } 

简单地说,我会说。 使用authorizeUrls()指定第二行,但指定基本身份validation所需的URL。 而不是formLogin()使用httpBasic()

 @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeUrls().antMatchers("/", "/index", "/user/**", "/about").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and().formLogin() .loginUrl("/login") .failureUrl("/login-error") .loginProcessingUrl("/security_check") .usernameParameter("j_username").passwordParameter("j_password") .permitAll(); http.authorizeUrls().antMatchers("/api/*").hasRole("YOUR_ROLE_HERE").and().httpBasic(); http.logout().logoutUrl("/logout"); http.rememberMe().rememberMeServices(rememberMeServices()).key("password"); } 

这样的事情应该有效。

链接: HttpSecurityHttpBasicConfgurer

你可以通过在第一个配置中的http之后添加.antMatcher("/api/**")来解决它,只管理/api urls。 你必须在第一个适配器上拥有它:

 http .antMatcher("/api/*") .authorizeRequests() .antMatchers("^/api/.+$").hasRole("ADMIN") .... 

显然,随着Spring的更新,这些往往会淡化其适用性。 运行spring spring starter security 1.4.0.RELEASE这是我的解决方案。 我的用例有点不同,因为我正在尝试使用基本身份validation来保护刷新端点以进行云配置,并使用具有spring会话的网关在所有其他实例中传递身份validation。

 @EnableWebSecurity @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal1(AuthenticationManagerBuilder auth) throws Exception { //try in memory auth with no users to support the case that this will allow for users that are logged in to go anywhere auth.inMemoryAuthentication(); } @Override protected void configure(HttpSecurity http) throws Exception { http .httpBasic() .disable() .authorizeRequests() .antMatchers(HttpMethod.POST, "/user").permitAll() .anyRequest().authenticated() .and() .csrf().disable(); } @Bean public BCryptPasswordEncoder encoder() { return new BCryptPasswordEncoder(11); } @Configuration @Order(1) public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { @Autowired private AuthenticationProvider customAuthenticationProvider; @Autowired protected void configureGlobal2(AuthenticationManagerBuilder auth) throws Exception { auth .authenticationProvider(customAuthenticationProvider); } @Override protected void configure(HttpSecurity http) throws Exception { http .httpBasic() .and() .authorizeRequests() .antMatchers(HttpMethod.POST, "/refresh").hasRole("SUPER") .and() .csrf().disable(); } } } 

请参阅spring security文档以获得进一步说明: Spring Security

基本思想是@Order注释将决定auth方案的运行顺序。 没有@Order意味着它是最后一个。 如果authorizeRequests()部分在传入的URL上不匹配,则该配置将通过,下一个配置将尝试进行身份validation。 这将继续,直到身份validation成功或失败。

这里的其他答案相对较旧,例如,我在Spring 4中找不到authorizeUrls

在SpringBoot 1.4.0 / Spring 4中,我已经实现了这样的基本/表单登录:

 @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { protected void configure (HttpSecurity aHttp) throws Exception { aHttp.authorizeRequests ().antMatchers (("/api/**")).fullyAuthenticated ().and ().httpBasic (); aHttp.formLogin () .loginPage ("/login").permitAll () .and ().logout ().permitAll (); } } 

可能有更多优雅的写作方式 – 我仍然在努力理解这个构建器如何在序列等方面工作。 但这很有效。