我一直在使用Spring构建REST API。我使用Spring Security(3.2)进行基本身份验证,并且我遇到了一个问题,即任何未经身份验证的请求都会导致404错误,即使执行了AuthenticationEntryPoint(无论如何,Spring应该给我401一个我知道默认情况下)。在我的浏览器中请求资源,我甚至没有提示输入凭据。这是问题的屏幕截图:
在阅读了有关该主题的文档和一些教程后,我似乎无法找到我出错的地方。我能想象到的唯一一件事就是被抓住了。
Spring Security配置:
@Slf4j
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final String REALM_NAME = "Autopulse API";
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
// Set to stateless authentication.
httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.csrf().disable();
httpSecurity.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
httpSecurity.userDetailsService(userDetailsService);
httpSecurity.authorizeRequests()
.antMatchers("/make/private").authenticated();
httpSecurity.httpBasic().realmName(REALM_NAME);
}
}
身份验证入口点:
@Slf4j
@Component
public class HttpBasicAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
控制器:
@Slf4j
@RestController
@RequestMapping("/make")
public class MakeController {
@RequestMapping(value = "/private", method = RequestMethod.GET)
public String getPrivateStuff() {
return "private things!";
}
}
当我在Authorization标头中提供有效用户凭据时,我可以看到受保护的资源("私事!"),但是如果我不提供授权标头,或者我输入了无效的凭据,我只是得到404错误。如果需要,我可以附加我的用户详细信息服务和用户详细信息类。
答案 0 :(得分:1)
我明白了。问题归结为Spring和异常处理。我有一个名为ExceptionController的类,它看起来像:
@Slf4j
@RestController
@ControllerAdvice
public class ExceptionController implements ErrorController {
// @ExceptionHandler methods here.
@Override
public String getErrorPath() {
return null;
}
}
事实证明,通过实现ErrorController,我将控制权交给了这个类,在认证入口点之后,Spring无法找到合适的方法,最终会抛出不需要的404错误。解决方法是删除这些细节:
@Slf4j
@RestController
@ControllerAdvice
public class ExceptionController {
// @ExceptionHandler methods here.
}