简体   繁体   English

如何从 JAX-WS Webservice 中的编程授权检查返回正确的 HTTP 状态代码?

[英]How to return proper HTTP Status code from programmatic authorization check in JAX-WS Webservice?

I have a Webservice like the following simplified example deployed on JBoss EAP 6 (JBoss AS 7):我在 JBoss EAP 6 (JBoss AS 7) 上部署了一个类似于以下简化示例的 Web 服务:

@Stateless
@RolesAllowed("basic_role")
@WebService(name = "MyWebService", serviceName = "MyWebService")
@WebContext(contextRoot = "api", urlPattern = "/MyWebService", authMethod = "BASIC")
public class MyWebService {

    @Resource
    private WebServiceContext webServiceContext;

    @WebMethod
    public void doSomething(String parameter) {
        System.out.println(webServiceContext.getUserPrincipal());
        if (!webServiceContext.isUserInRole("role_for_parameter_" + parameter)) {
            throw new HTTPException(401);
        }
    }
}

I want to do a permission check based on the parameter passed in, but I do not know how to properly return a 401 status code.我想根据传入的参数进行权限检查,但我不知道如何正确返回 401 状态代码。 If the caller does not provide any credentials or the provided user does not have the "basic_role", the server returns 401 as expected.如果调用者没有提供任何凭据或提供的用户没有“basic_role”,服务器将按预期返回 401。 But once my code is called, if I throw any kind of exception, a status code 500 is returned.但是一旦我的代码被调用,如果我抛出任何类型的异常,就会返回状态代码 500。 I thought this was what the HTTPException was for, but it makes no difference if I use HTTPException or RuntimeException or any other Exception I tried.我认为这就是 HTTPException 的用途,但是如果我使用 HTTPException 或 RuntimeException 或我尝试过的任何其他异常,这没有区别。

The only way I could come up with is this:我能想出的唯一方法是:

@WebMethod
public void doSomething(String parameter) {
    System.out.println(webServiceContext.getUserPrincipal());
    if (!webServiceContext.isUserInRole("role_for_parameter_" + parameter)) {
        HttpServletResponse response = (HttpServletResponse)webServiceContext.getMessageContext().get(MessageContext.SERVLET_RESPONSE);
        try {
            response.sendError(401, "Not authorized");
            throw new RuntimeException("Not authorized");
        }
        catch (IOException e) {
            throw propagate(e);
        }
    }
}

This way, the 401 status code is returned, but I need to throw the exception as well to prevent further processing, and it seems from the logs that JAX-WS tries to return a 500 with the RuntimeException, only it can't because the response is already commited.这样,返回 401 状态代码,但我也需要抛出异常以防止进一步处理,而且从日志看来,JAX-WS 试图返回 500 和 RuntimeException,只是它不能,因为响应已经提交。 This doesn't seem to be a clean way to do it.这似乎不是一种干净的方法。

Not sure it's the best method, but works for me:不确定这是最好的方法,但对我有用:

webServiceContext.getMessageContext()
     .put(MessageContext.HTTP_RESPONSE_CODE, HttpStatus.UNAUTHORIZED_401);
return;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM