使用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"); }
这样的事情应该有效。
链接: HttpSecurity
, HttpBasicConfgurer
。
你可以通过在第一个配置中的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 (); } }
可能有更多优雅的写作方式 – 我仍然在努力理解这个构建器如何在序列等方面工作。 但这很有效。