我是JAX-WS的新手,有一件我不明白的事情。
有很多关于如何设置JAX-WS安全性的教程,但几乎所有情况下BindingProvider.USERNAME_PROPERTY和BindingProvider.PASSWORD_PROPERTY都存储在某个.xml文件中(取决于我认为的容器) - 它们是“硬编码”就是这样。这就是我没有得到的。如何通过将BindingProvider.USERNAME_PROPERTY和BindingProvider.PASSWORD_PROPERTY与数据库中的用户名和密码进行比较来验证Web服务客户端?我尝试在客户端设置BindingProvider.USERNAME_PROPERTY和BindingProvider.PASSWORD_PROPERTY,如下所示:
ShopingCartService scs = new ShopingCartService(wsdlURL, name);
ShopingCart sc = scs.getShopingCartPort();
Map<String, Object> requestContext = ((BindingProvider)sc).getRequestContext();
requestContext.put(BindingProvider.USERNAME_PROPERTY, userName);
requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);
sc.someFunctionCall();
然后,在服务器端检索如下:
@Resource
WebServiceContext wsContext;
@WebMethod
public void someFunctionCall() {
MessageContext mc = wsContext.getMessageContext();
mc.get(BindingProvider.USERNAME_PROPERTY);
mc.get(BindingProvider.PASSWORD_PROPERTY);
}
但是我总是得到null,我没有在xml中设置任何东西,web服务工作得很好,除了我不能得到那些变量:(
我在java 1.6,tomcat 6和JAX-WS上运行。
非常感谢使用数据库中的密码验证用户的任何帮助, 感谢。
答案 0 :(得分:19)
我认为您正在寻找应用程序级别的JAX-WS身份验证,而不是服务器级别的HTTP基础知识。请参阅以下完整示例:
Application Authentication with JAX-WS
在Web服务客户端站点上,只需将“用户名”和“密码”放入请求标题中。
Map<String, Object> req_ctx = ((BindingProvider)port).getRequestContext();
req_ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, WS_URL);
Map<String, List<String>> headers = new HashMap<String, List<String>>();
headers.put("Username", Collections.singletonList("someUser"));
headers.put("Password", Collections.singletonList("somePass"));
req_ctx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
在Web服务服务器站点上,通过WebServiceContext获取请求标头参数。
@Resource
WebServiceContext wsctx;
@WebMethod
public String method() {
MessageContext mctx = wsctx.getMessageContext();
Map http_headers = (Map) mctx.get(MessageContext.HTTP_REQUEST_HEADERS);
List userList = (List) http_headers.get("Username");
List passList = (List) http_headers.get("Password");
//...
答案 1 :(得分:12)
BindingProvider.USERNAME_PROPERTY和BindingProvider.PASSWORD_PROPERTY匹配HTTP基本身份验证机制,该机制在HTTP级别启用身份验证过程,而不是在应用程序或servlet级别启用身份验证过程。
基本上,只有HTTP服务器才能知道用户名和密码(最终根据HTTP /应用服务器规范知道应用程序,例如Apache / PHP)。 使用Tomcat / Java,在web.xml中添加登录配置BASIC和相应的安全约束/安全角色(稍后将与用户/真实用户组关联的角色)。
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>YourRealm</realm-name>
</login-config>
然后,将HTTP服务器(或应用程序服务器)级别的域与相应的用户存储库连接。对于tomcat,您可以查看适合您需求的JAASRealm,JDBCRealm或DataSourceRealm。
答案 2 :(得分:6)
我遇到了同样的问题,并在此处找到了解决方案:
http://www.mastertheboss.com/web-interfaces/336-jax-ws-basic-authentication.html?start=1
祝你好运答案 3 :(得分:1)
对于使用两者的示例,应用程序级别的身份验证和HTTP基本身份验证请参阅我的previous posts之一。
答案 4 :(得分:1)
我面对类似的情况,我需要提供给我的WS:用户名,密码和WSS密码类型。
我最初使用的是“Http Basic Auth”(作为@ahoge),我试图使用@ Philipp-Dev的引用。太。我没有得到成功的解决方案。
在google上进行了一些深入的搜索之后,我发现了这个帖子:
https://stackoverflow.com/a/3117841/1223901
还有我的问题解决方案
我希望这可以帮助其他任何人,比如帮助我。
RGDS, iVieL
答案 5 :(得分:1)
在客户端SOAP处理程序中,您需要按如下所示设置javax.xml.ws.security.auth.username和javax.xml.ws.security.auth.password属性:
public class ClientHandler implements SOAPHandler<SOAPMessageContext>{
public boolean handleMessage(final SOAPMessageContext soapMessageContext)
{
final Boolean outInd = (Boolean)soapMessageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outInd.booleanValue())
{
try
{
soapMessageContext.put("javax.xml.ws.security.auth.username", <ClientUserName>);
soapMessageContext.put("javax.xml.ws.security.auth.password", <ClientPassword>);
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
}
return true;
}
}
答案 6 :(得分:0)
如果您通过这种方式将客户端的用户名和密码放入请求中,则:
URL url = new URL("http://localhost:8080/myapplication?wsdl");
MyWebService webservice = new MyWebServiceImplService(url).getMyWebServiceImplPort();
Map<String, Object> requestContext = ((BindingProvider) webservice).getRequestContext();
requestContext.put(BindingProvider.USERNAME_PROPERTY, "myusername");
requestContext.put(BindingProvider.PASSWORD_PROPERTY, "mypassword");
并致电您的网络服务
String response = webservice.someMethodAtMyWebservice("test");
然后,您可以在服务器端读取这样的基本身份验证字符串(您必须添加一些检查并执行一些异常处理):
@Resource
WebServiceContext webserviceContext;
public void someMethodAtMyWebservice(String parameter) {
MessageContext messageContext = webserviceContext.getMessageContext();
Map<String, ?> httpRequestHeaders = (Map<String, ?>) messageContext.get(MessageContext.HTTP_REQUEST_HEADERS);
List<?> authorizationList = (List<?>) httpRequestHeaders.get("Authorization");
if (authorizationList != null && !authorizationList.isEmpty()) {
String basicString = (String) authorizationList.get(0);
String encodedBasicString = basicString.substring("Basic ".length());
String decoded = new String(Base64.getDecoder().decode(encodedBasicString), StandardCharsets.UTF_8);
String[] splitter = decoded.split(":");
String usernameFromBasicAuth = splitter[0];
String passwordFromBasicAuth = splitter[1];
}