我想根据我的请求类型配置网络安全层。
如果请求以 /rest 开头,则应使用带有无状态 session 管理的基本身份验证,对于登录身份验证,则应使用带有状态 session 管理的 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();
}
它适用于基本身份验证,但不适用于登录请求,因为 session 没有状态。谁能帮我配置 Spring 安全性。我是 Spring 安全新手。
最佳答案
你需要
1. Rest API需要进行基本认证
2. 您的 Web 应用程序通过表单登录进行身份验证。
授权是这两种情况的另一部分,您可以根据您的要求进行设置。
让我解释一下您的方法有什么问题。通过您的方法,您只能从一种配置实现一个身份验证入口点。即,您无法实现多个身份验证入口点。
现在来满足您的第一个要求:实现多个身份验证入口点。
1. 对于 Rest API 资源 -- 通过 HttpBasicAuthentication 进行身份验证 针对 antMatcher /rest/**
2. 对于 WebApp 资源 - 通过表单登录进行身份验证 除 /rest/**
实现这一目标
1. 您需要实现不同配置顺序和不同antMatcher模式的WebSecurityConfigurerAdapter
。
2. 每个配置的顺序很重要。
- 通配符模式(/**
) 应放在最后一个订单
- 非通配符模式或限制模式(/rest/**
)应放在第一位
3. 由于这些配置类是静态的,并且是注释为 @EnableWebSecurity
的类的内部类,因此在使用 @bean
定义 bean 和使用 @ Autowiring 时应该小心自动连线
。
Note:
Most of people makes mistake by not defining antmather for authorizeRequest()
If first configuration@Order(1)
class is configured as below
http.authorizeRequests()
2nd configuration will become dead configuration because
http.authorizeRequests() => http.antMatcher("/**").authorizeRequests()
And all URL's will be configured only for first configuration only.
请参阅下面给出的代码以更好地理解。
@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");
}
}
}
此问题需要不同的身份验证过滤器使用不同的 URL 集(/rest/**
和 /rest/**
除外)。这里,用户(对于基本身份验证和表单登录)可以根据单个表(例如 user_details)或多个表(例如 api_users
和 web_users
)进行身份验证
如果您有这样的要求,例如没有不同的 URL 集,但两组用户都说 customer
和 employees
(staff
) 都是访问相同的应用程序,但需要针对不同的表(例如用户和客户表)进行身份验证,在这种情况下请引用我的另一个答案 Spring Security user authentication against customers and employee table
关于java - 如何根据请求类型使用Spring Security管理 session ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58194759/