在 Spring Boot Web 应用程序中,我有以下安全配置:
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers().frameOptions().disable()
.and()
.antMatcher("/**").authorizeRequests()
.antMatchers("/actuator/health").permitAll()
.antMatchers("/actuator/**").hasAuthority(Authority.Type.ROLE_ADMIN.getName())
.antMatchers("/login/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/login")
.failureUrl("/login?error").permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.and()
.csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
.addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
// @formatter:on
}
现在,当我尝试访问以下网址时:
/api/v1.0/user
,它会将我重定向到/api/login
页面。
如何配置它以返回
403 Forbidden
而不是重定向到登录页面?
这是一个社区答案:
问题:
禁止的网址返回登录页面内容(而不是 403 状态代码)。
我有这个代码:
...
http.authorizeRequests().antMatchers("/uri/**").hasAuthority("SOME_ROLE");
根据Tong的建议进行了更改:
...
http.exceptionHandling().authenticationEntryPoint(new Http403ForbiddenEntryPoint());
http.authorizeRequests().antMatchers("/uri/**").hasAuthority("SOME_ROLE");
接受的解决方案对我不起作用。每个未经授权的请求都会重定向到登录页面,无论是 /api/* RESTful 请求还是网页。
以下是有效的方法:创建一个产生 403 错误的公共端点并修改现有的过滤器,这样,如果 URI 包含“/api”并且没有经过身份验证的主体,它将请求重定向到自定义 403 处理程序。
控制器:
@RestController
@RequestMapping("/api/error")
public class ApiErrorHandlerController {
@RequestMapping("/403")
public ResponseEntity<String> forbidden403(){
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
}
过滤器:
SecurityContextImpl sci = (SecurityContextImpl)
((HttpServletRequest)request).getSession()
.getAttribute("SPRING_SECURITY_CONTEXT");
if (sci == null && ((HttpServletRequest)request).getRequestURI().indexOf("/api/") == 0 ){
request = new HttpServletRequestWrapper((HttpServletRequest) request) {
@Override
public String getRequestURI() {
return "/api/error/403";
}
};
}
当然还有 Spring Security 规则:
...
authz.requestMatchers("/api/error/403").permitAll()
...