我想根据我的请求类型配置网络安全层。
如果请求以/ rest开头,则它应将Basic身份验证与无状态会话管理一起使用,而对于登录身份验证,则它应将CSRF与状态会话管理一起使用。
我尝试过下面的代码。
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/rest/**").hasRole("SUPER_ADMIN")
.anyRequest().fullyAuthenticated()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.formLogin().and().logout().permitAll()
;
}
它可用于基本身份验证,但不适用于登录请求,因为会话不是有状态的。谁能帮助我配置Spring安全性。我是Spring安全的新手。在此先感谢
您必须允许用户无需身份验证即可访问登录页面,与使用静态页面一样。请参阅以下配置。
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Bean
@Override
public UserDetailsService userDetailsService() {
UserDetails user =
User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}
您需要1.其余的API将通过基本身份验证进行身份验证2.您的Web应用程序将通过表单登录进行身份验证。在这两种情况下,授权都是另一部分,您可以根据需要进行设置。
让我解释一下您的方法出了什么问题。通过您的方法,您只能从一种配置中获得一个身份验证入口点。也就是说,您无法实现多个身份验证入口点。
现在是您实现多个身份验证入口点的第一个要求。1.对于Rest API资源-通过HttpBasicAuthentication进行身份验证 对于antMatcher /rest/**
2.对于WebApp资源-通过表单登录进行身份验证 对于/rest/**
以外的antMatcher,>
要实现这一目标
1.您需要具有不同配置顺序和不同antMatcher模式的WebSecurityConfigurerAdapter
实现。2.每个配置的顺序很重要。-通配符模式(/**
)应该排在最后-非通配符模式或受限模式(/rest/**
)应该放在第一位3.由于这些配置类是静态类,而对于带有注解@EnableWebSecurity
的类来说是内部类,因此在使用@bean
定义bean和使用@Autowired
自动装配时应格外小心。注:大多数人通过不为authorizeRequest()定义蚂蚁来犯错如果第一个配置
@Order(1)
类的配置如下http.authorizeRequests()
第二个配置将变为无效配置,因为http.authorizeRequests() => http.antMatcher("/**").authorizeRequests()
并且所有URL仅将被配置为仅用于第一配置。请参阅下面提供的代码,以更好地理解。
@Configuration @EnableWebSecurity public class SpringSecurityConfiguration { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Configuration @Order(1) public static class BasicAuthSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private PasswordEncoder passwordEncoder; @Autowired public void configureInMemoryAuthentication(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("superadmin") .password(passwordEncoder.encode("superadmin@123#")) .roles("SUPER_ADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .antMatcher("/rest/**") .authorizeRequests() .antMatchers("/rest/**").hasRole("SUPER_ADMIN") .and().httpBasic(); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); } } @Configuration @Order(2) public static class LoginFormSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private PasswordEncoder passwordEncoder; @Autowired public void configureInMemoryAuthentication(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user") .password(passwordEncoder.encode("user@123#")) .roles("USER"); } @Override protected void configure(HttpSecurity http) throws Exception { http .antMatcher("/**") //wild card i.e, allow all (But already /rest/** is filtered by 1st config) .authorizeRequests() .antMatchers("/resources/**").permitAll() .antMatchers("/**").authenticated() .and().formLogin() .defaultSuccessUrl("/app/user/dashboard") .and().exceptionHandling() .accessDeniedPage("/403") .and().logout() .invalidateHttpSession(true); http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired"); } } }