【发布时间】:2026-01-05 12:30:01
【问题描述】:
我已按照以下说明为管理员和用户创建了两个不同的 http 安全块。 docs.spring.io/spring-security-multiple-httpsecurity
如文档所述,如果 URL 不以 /aaa 开头,则将使用另一个配置进行模式。
但是当我将 @Order(1) 放在管理块时,管理页面工作正常,用户页面不会重定向到登录页面 /login/user
当我将 @Order(1) 放在用户块时,用户页面工作正常,管理页面也不会重定向到登录页面 /login/admin。
这是我的java代码
@EnableWebSecurity
public class MultiHttpSecurityConfig {
/**
* intercept user url
*/
@Configuration
@Order(1)
public static class UserWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
CustomAuthenticationSuccessHandler successHandler;
@Autowired
CustomAuthenticationFailureHandler failureHandler;
@Autowired
private CustomAuthenticationProvider customAuthProvider;
@Autowired
private CustomUserDetailsService userDetailsService;
@Value("${my.cookie.timeout}")
private int cookieTimeOut;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/images/**, /fonts/**").permitAll()
.antMatchers("/bbb/**","/aaaa/**").hasAnyRole("USER");
http.formLogin()
.successHandler(successHandler)
.failureHandler(failureHandler)
.loginPage("/login/user").permitAll();
http.logout().permitAll();
http.rememberMe().key("uniqueAndSecret").tokenValiditySeconds(cookieTimeOut);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthProvider);
auth.userDetailsService(userDetailsService);
}
}
/**
* intercept admin url
*/
@Configuration
public static class AdminWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
CustomAuthenticationSuccessHandler successHandler;
@Autowired
CustomAuthenticationFailureHandler failureHandler;
@Value("${my.cookie.timeout}")
private int cookieTimeOut;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/images/**, /fonts/**").permitAll()
.antMatchers("/ccc/**","/dddd").hasAnyRole("ADMIN");
http.formLogin()
.successHandler(successHandler)
.failureHandler(failureHandler)
.loginPage("/login/admin").permitAll();
http.logout().permitAll();
http.rememberMe().key("uniqueAndSecret").tokenValiditySeconds(cookieTimeOut);
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("test").password("test").roles("ADMIN");
}
}
}
更新:
如下 dur 所说,关键原因是 authorizeRequests() 方法匹配 Order(1) 中的所有 url,所以我需要添加 antMatcher("/bbb/* >")** 首先在 authorizeRequests() 之前。
但 antMatcher() 只匹配一种 url ,如果我还有一种 url 要匹配,例如 "/bbb/" , "/aaa/*" ,如何实现这 ? 然后我需要再添加一个 WebSecurityConfigurerAdapter 配置? 有没有更好的方法来减少代码?
我在 spring-security SDK requestMatchers() 方法中找到了解决方案,它在 requestMatchers() 方法上方提供了一个示例。
下面是我在 Order(1) 处匹配用户网址的代码
http.csrf().disable();
http.requestMatchers()
.antMatchers("/bbb/**", "/aaa/**")
.and()
.authorizeRequests()
.antMatchers("/**").hasAnyRole("USER");
http.formLogin()
.successHandler(successHandler)
.failureHandler(failureHandler)
.loginPage("/login/user").permitAll();
http.logout().permitAll();
那么bbb和aaa都已经匹配好了,不需要再创建配置
但是又出现了一个问题,当将用户名和密码发布到登录/用户界面时会显示“405 method not allowed”登录页面,而管理页面工作正常
我搜索了谷歌,它告诉我要禁用 csrf,但我已经禁用 csrf...
【问题讨论】:
-
两种配置都适用于
/**(任何请求),所以使用第一个。如果您添加订单,则使用订单最低的订单。
标签: java spring spring-boot spring-security