如何为Spring MVC / Security restful Web服务创建自定义JSON 401页面?

时间:2012-07-12 09:04:28

标签: java spring spring-mvc spring-security

我正在尝试使用Servlet 3.0,Spring MVC和Spring Security创建安全的restful 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>

但我更喜欢用编程方式或通过注释配置。

2 个答案:

答案 0 :(得分:4)

在Spring 3.0中,有一个注释ResponseStatus

我像这样使用这个注释;

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

这有用吗?

答案 1 :(得分: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();
}