2

我正在尝试使用 Servlet 3.0、Spring MVC 和 Spring Security 创建一个安全的静态 Web 服务。我想在 401 上返回自定义 JSON 消息,而不是 Servlet 容器返回的默认 HTML 消息。

我尝试了几种方法,但似乎无法使其正常工作。

我的控制器如下所示::

@Controller
@RequestMapping("/")
public class ApplicationController {

    private ApplicationFactory applicationFactory;

    @Inject
    public ApplicationController(ApplicationFactory applicationFactory) {
        super();
        this.applicationFactory = applicationFactory;
    }

    @RequestMapping(method = GET)
    @ResponseBody
    @Secured("ROLE_USER")
    public Application getApplicationInfo() {
        return applicationFactory.buildApplication(this);
    }

}

我的 Spring Security 上下文如下所示:

<security:global-method-security secured-annotations="enabled" mode="aspectj" />

<security:http auto-config="true" use-expressions="true">
<security:http-basic />
</security:http>

我尝试添加以下内容:

@ExceptionHandler(AccessDeniedException.class)
@ResponseBody
public Application accessDenied() {
    return applicationFactory.buildApplication(this);
}

但它会被忽略。我尝试将“access-denied-page="/denied"” 添加到我的 security:http 标记中,并在我的控制器中使用以下内容:

@RequestMapping(value = "/denied", method = GET)
@ResponseBody
public Application accessDenied() {
    return applicationFactory.buildApplication(this);
}

但它会被忽略。我尝试了一个自定义访问被拒绝处理程序,如下所示:

<security:http auto-config="true" use-expressions="true">
<security:http-basic />
<security:access-denied-handler ref="jsonAccessDeniedHandler" />
</security:http>

唯一似乎有效的是以下内容:

@ExceptionHandler(Exception.class)
@ResponseBody
public Application accessDenied() {
    return applicationFactory.buildApplication(this);
}

但这可以捕获所有内容,我只想自定义失败的身份验证。

最后,将它添加到我的 web.xml 也可以:

<error-page>
<error-code>401</error-code>
<location>/401</location>
</error-page>

但我更愿意以编程方式或通过注释进行配置。

4

2 回答 2

4

在 spring 3.0 中有一个注释 ResponseStatus

我像这样使用这个注释;

@ResponseStatus(value = 401)
@ExceptionHandler(value = HttpMessageNotReadableException.class)
@ResponseBody
public ErrorResponse handleJsonMappingException(HttpMessageNotReadableException e) {

这有帮助吗?

于 2012-07-12T09:17:40.357 回答
0

要使用 @ResponseBody 并操作响应标头,请执行以下操作:

@RequestMapping(value = "/url", method = RequestMethod.GET, headers = { "Accept=application/json" })
public @ResponseBody
List handle(HttpServletResponse response,
@RequestHeader("headerID") String headerString) {
response.setHeader("responseHeaderProperty", String);
return service.doSomething();
}
于 2012-07-12T11:26:54.503 回答