你需要
1. Rest API 需要通过基本认证进行认证
2.您的Web应用程序通过表单登录进行身份验证。
在这两种情况下,授权都是另一部分,您可以根据自己的要求进行设置。
让我解释一下你的方法有什么问题。通过您的方法,您只能从一种配置中实现一个身份验证入口点。即,您无法实现多个身份验证入口点。
现在您的第一个要求是实现多个身份验证入口点。
1. 对于 Rest API 资源 -- 通过 HttpBasicAuthentication 进行身份验证 for antMatcher /rest/**
2. WebApp 资源 -- Form Login 认证 /rest/**以外的antMatcher
实现这一目标
1.你需要有不同配置顺序和不同antMatcher模式的WebSecurityConfigurerAdapter的实现。
2.每个配置的顺序很重要。
- 通配符模式(/**) 应放在最后一个订单
- 非通配符模式或受限模式(/rest/**) 应优先放置
3. 由于这些配置类是注解 @EnableWebSecurity 的类的静态和内部类,因此在使用 @bean 定义 bean 和使用 @Autowired 自动装配时应小心。
注意:
大多数人都会犯错误,因为没有为 authorizeRequest() 定义 antmather
如果第一次配置@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");
}
}
}
此问题要求针对不同的身份验证过滤器使用不同的 URL 集(/rest/** 和 other than /rest/**)。这里用户(用于基本身份验证和表单登录)可以针对单个表(例如 user_details)或多个表(例如 api_users 和 web_users)进行身份验证
如果您的要求是没有不同的 URL 集,但两组用户说 customer 和 employees(staff) 都在访问同一个应用程序,但他们需要针对不同的表进行身份验证(比如用户和客户表)在这种情况下,请参考我的另一个答案Spring Security user authentication against customers and employee table