【发布时间】:2019-09-08 18:21:06
【问题描述】:
我有一个 Spring Boot 应用程序设置,使用 SpringSecurity 和 OneLogin 作为 JWT 令牌提供程序。
WebConfig 类如下所示:
@EnableResourceServer
@EnableWebSecurity
@Configuration
public class WebConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
web.ignoring().mvcMatchers(
"/actuator/info",
"/actuator/health",
"/someArbitraryPath/**");
}
}
到目前为止,一切都很好,除了上述端点之外的所有端点都是安全的,并且只有在传入(有效的)JWT 令牌时才能工作。上面配置的似乎在根本不传递身份验证标头时有效,这正是我打算做的。
除了...当“/someArbitraryPath/someDto/”下的两个调用之一引发异常时,该异常被配置为返回 ResponseStatus“NOT_FOUND”,结果我得到 401。
所以,在“/someArbitraryPath”下,我有以下(向公众开放)REST 控制器:
@RestController
@RequestMapping("/someArbitraryPath")
public class SomeArbitraryApiController {
private final SomeArbitraryService service;
private final SomeArbitraryDtoMapper dtoMapper;
public SomeArbitraryApiController(SomeArbitraryService service, SomeArbitraryDtoMapper dtoMapper) {
this.service = service;
this.dtoMapper = dtoMapper;
}
@GetMapping(value = "/someDtosList", params = {"page", "size"})
@Transactional(readOnly = true)
public SomePageDto getSomeDtoPage(
@RequestParam(value = "page", required = false, defaultValue = "0") int page,
@RequestParam(value = "size", required = false, defaultValue = "250") int size) {
Page<SomeObject> someDtoPage = service.searchPageOfSomeObjects(page, size);
List<SomeDto> someDtoList = dtoMapper.someObjectsToDtos(someDtoPage.getContent());
PageDto pageDto = new PageDto(size, someDtoPage.getTotalElements(), someDtoPage.getTotalPages(), page);
return new SomePageDto(someDtoList, pageDto);
}
@GetMapping("/someDtosList/{dtoId}")
@Transactional(readOnly = true)
public SomeDto getSomeDtoById(@PathVariable(value = "dtoId") String dtoId) {
return dtoMapper.objectToDto(
service.getSomeObjectById(dtoId)
);
}
}
两者的最后一次调用,即检索特定 SomeDto 对象的调用,可能会引发 ResourceNotFoundException,该异常被配置为返回 ResponseStatus NOT_FOUND:
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String resourceName, String fieldName, Object fieldValue) {
super(String.format("%s not found with %s : '%s'", resourceName, fieldName, fieldValue));
}
}
然而,当调用这个 unsecured 时,这不会返回 404 HTTP 状态 - 这会返回一个 401 Unauthorized:
{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
}
但是,当我在 RestController 中明确捕获异常并将 HttpServletResponse 对象上的响应状态设置为
response.setStatus(HttpStatus.SC_NOT_FOUND);
然后我确实得到了 404。但不是我想要的(我不想重新配置相同的错误对象,对吧)。
当我使用有效的 JWT 令牌调用此端点时,它会以正确的正文返回正确的 404 错误。
我做错了什么?
【问题讨论】:
标签: java spring spring-boot spring-security