访问安全的JAX-WS EJB Web服务

时间:2017-08-22 08:02:43

标签: web-services ejb jax-ws basic-authentication java-ee-7

如何访问EJB实现的安全Soap Web服务:

@Stateless
@DeclareRoles({"Boss"})
@WebService(name="SoapService", serviceName="SoapWS", portName="SoapWSPort")
public class SoapServiceImpl implements SoapService {

    @RolesAllowed({"Boss"})
    public SoapThing getSoapThing(String name, String prepend) throws SoapThingyException {
        ...
    }
}

web.xml包含:

<login-config>
     <auth-method>BASIC</auth-method>         
     <realm-name>ApplicationRealm</realm-name>
</login-config>

我为客户端创建了一个SoapHandler,为请求添加了Authorization标头,如下所示:

public boolean handleMessage(SOAPMessageContext context) {
    try {
        String credential = Base64.getEncoder().encodeToString((username+":"+password).getBytes("UTF-8"));
        Map<String, Object> httpHeaders = null;
        if (context.get(MessageContext.HTTP_REQUEST_HEADERS) != null) {         
            httpHeaders = (Map<String, Object>)context.get(MessageContext.HTTP_REQUEST_HEADERS);
        } else {
            httpHeaders = new HashMap<>();
        }       
        httpHeaders.put("Authorization", Arrays.asList("Basic " + credential.substring(0, credential.length()-1)));
        context.put(MessageContext.HTTP_REQUEST_HEADERS, httpHeaders);
        return true;
    } catch (UnsupportedEncodingException e) {
        return false;
    }
}

我的客户端是一个独立的Java应用程序,使用wsimport生成的存根,并将处理程序添加到BindingProvider:

SoapWS service = new SoapWS();      
SoapService port = service.getSoapWSPort();
((BindingProvider)port).getBinding().setHandlerChain(Arrays.asList(new CredentialHandler("spike", "*****")));
SoapThing st = port.getSoapThingByNumber(1);

...它执行正常,将凭据添加到Authorization标头但我仍然从服务器收到未经授权的响应:

Exception in thread "main" com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 401: Unauthorized

Web服务部署在Wildfly上,用户被分配到ApplicationRealm,角色管理员,分组Dog and Boss:

enter image description here

我错过了什么?

1 个答案:

答案 0 :(得分:1)

在JAX-WS客户端中使用基本身份验证比这更容易:

SoapWS service = new SoapWS();      
SoapService port = service.getSoapWSPort();
Map<String,Object> requestContext = ((BindingProvider)port).getRequestContext();
requestContext.put(BindingProvider.USERNAME_PROPERTY, username);
requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);

SoapThing st = port.getSoapThingByNumber(1);

不需要处理程序。

JAX-WS客户端机器自动处理HTTP 401挑战。