Spring Security中端点hasAuthority权限校验失效问题排查
解决Spring Security中Actuator与Administration端点权限校验不生效的问题
你的问题出在重复使用.authorizeRequests()方法导致授权规则顺序失效。Spring Security的授权规则是按声明的先后顺序匹配的,你第一个.authorizeRequests()块里的.anyRequest().authenticated()已经匹配了所有未被前面permitAll覆盖的请求,第二个.authorizeRequests()块里的规则根本不会被执行——这就是为什么所有已认证用户都能访问/actuator/**和/administration/**的原因。
修复后的完整配置代码
// @formatter:off httpSecurity .authorizeRequests() // 允许所有用户访问的公共端点 .antMatchers( Utils.MAPPING_INDEX, Utils.MAPPING_ARTICLE, Utils.MAPPING_IMAGE, Utils.MAPPING_ERROR, Utils.MAPPING_VERIFY_MAIL, Utils.MAPPING_REGISTER, Utils.MAPPING_LOGIN, Utils.MAPPING_LOGIN_ERROR, Utils.MAPPING_LOGIN_VERIFIED, Utils.MAPPING_LOGIN_VERIFICATION_ERROR, Utils.MAPPING_RESET_PASSWORD, Utils.MAPPING_LOGIN_PASSWORD_RESET_SUCCESS, Utils.MAPPING_LOGIN_PASSWORD_RESET_LOCKED, Utils.MAPPING_RESET_PASSWORD_RESET_MAIL_SEND, Utils.MAPPING_LOGIN_PASSWORD_RESET_FAILURE, Utils.MAPPING_INDEX_LOGOUT_SUCCESS, Utils.MAPPING_REGISTER_SUCCESS, Utils.MAPPING_AUTHOR, Utils.MAPPING_CONTACT, Utils.MAPPING_CONTACT_SUCCESS, Utils.MAPPING_CONTACT_FAILURE, Utils.MAPPING_REPORT_WORKAROUND, "/test", "/test1", "/frag1", "/frag2", "/css/**", "/js/**", "/img/**", "/fonts/**", "/external/**", "/favicon.ico", "/favicon_32.ico", "/favicon.svg" ).permitAll() // 仅ADMIN权限用户可访问的端点(必须放在anyRequest之前) .antMatchers("/actuator/**", "/administration/**") .hasAuthority(Authority.ADMIN.name()) // 其余所有请求需要已认证 .anyRequest().authenticated() .and() .formLogin() .loginPage(Utils.MAPPING_LOGIN) .loginProcessingUrl(Utils.MAPPING_LOGIN) .usernameParameter("email") .passwordParameter("password") .successHandler(basicAuthenticationSuccessHandlerImpl) .failureUrl(Utils.MAPPING_LOGIN_ERROR) .and() .logout() .logoutUrl(Utils.MAPPING_INDEX) .logoutSuccessUrl(Utils.MAPPING_INDEX_LOGOUT_SUCCESS) .invalidateHttpSession(true) .and() .oauth2Login() .loginPage(Utils.MAPPING_LOGIN) .successHandler(oauth2AuthenticationSuccessHandler); // @formatter:on
关键说明
- 规则顺序至关重要:Spring Security会优先匹配第一个符合请求路径的规则,所以需要特殊权限校验的端点规则必须放在
.anyRequest().authenticated()前面,否则会被后者覆盖。 - 不要拆分多个
.authorizeRequests()块:每个.authorizeRequests()都会创建一个新的授权规则链,前面的链如果已经包含.anyRequest(),后面的链永远不会被执行。 - 确认权限名称正确性:确保
Authority.ADMIN.name()返回的字符串(比如"ADMIN")和用户实际拥有的权限名称完全一致(Spring Security权限默认区分大小写)。
这样调整后,只有拥有ADMIN权限的已认证用户才能访问/actuator/**和/administration/**,普通USER权限的用户访问这些端点会被拒绝。
内容的提问来源于stack exchange,提问作者Tomas Bisciak
相关产品推荐
相关产品推荐

