[英]How to authenticate soap based java web services?
我正在使用 Java 开发基于 Soap 的 web 服务。 谁能告诉我如何验证正在使用 web 服务的客户端?
谢谢。
我们可以实现的不同方式和不同类型的安全性:消息级安全性
最常见的是,我们将 WS-Security 用于 SOAP Web 服务。 WS-security 概要文件确定如何启用 WS-security。
例子:
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-6138db82-5a4c-4bf7-915f-af7a10d9ae96">
<wsse:Username>user</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">CBb7a2itQDgxVkqYnFtggUxtuqk=</wsse:Password>
<wsse:Nonce>5ABcqPZWb6ImI2E6tob8MQ==</wsse:Nonce>
<wsu:Created>2010-06-08T07:26:50Z</wsu:Created>
</wsse:UsernameToken>
上述元素包含在 SOAP header 中,如下所示:
SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.addHeader();
SOAPElement security = header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse");
SOAPElement username = usernameToken.addChildElement("Username", "wsse");
username.addTextNode(user);
SOAPElement password = usernameToken.addChildElement("Password", "wsse");
password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
password.addTextNode(encodedPass); //encodedPass = Base64 ( SHA-1 ( nonce + created + password ) )
SOAPElement nonce =
usernameToken.addChildElement("Nonce", "wsse");
nonce.addTextNode(Base64.encodeBytes(nonceString.getBytes()));
SOAPElement created = usernameToken.addChildElement("Created", "wsu","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
created.addTextNode(creatTime);
以下示例仅将用户和密码简单地添加到 HTTP header。
使用WebServiceContext接口的 JAX-WS 应用程序身份验证
WebServiceImpl.java
package com.javacodegeeks.enterprise.ws;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
@WebService(endpointInterface = "com.javacodegeeks.enterprise.ws.WebServiceInterface")
public class WebServiceImpl implements WebServiceInterface {
@Resource
WebServiceContext webServiceContext;
@Override
public String getHelloWorldAsString(String str) {
MessageContext messageContext = webServiceContext.getMessageContext();
// get request headers
Map<?,?> requestHeaders = (Map<?,?>) messageContext.get(MessageContext.HTTP_REQUEST_HEADERS);
List<?> usernameList = (List<?>) requestHeaders.get("username");
List<?> passwordList = (List<?>) requestHeaders.get("password");
String username = "";
String password = "";
if (usernameList != null) {
username = usernameList.get(0).toString();
}
if (passwordList != null) {
password = passwordList.get(0).toString();
}
// of course this is not real validation
// you should validate your users from stored databases credentials
if (username.equals("nikos") && password.equals("superpassword")) {
return "Valid User :"+str;
} else {
return "Unknown User!";
}
}
}
WebServiceClient.java
package com.javacodegeeks.enterprise.ws.client;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import javax.xml.ws.handler.MessageContext;
import com.javacodegeeks.enterprise.ws.WebServiceInterface;
public class WebServiceClient{
public static void main(String[] args) throws Exception {
URL wsdlUrl = new URL("http://localhost:8888/webservice/helloworld?wsdl");
//qualifier name ...
QName qname = new QName("http://ws.enterprise.javacodegeeks.com/", "WebServiceImplService");
Service service = Service.create(wsdlUrl, qname);
WebServiceInterface sayHello = service.getPort(WebServiceInterface.class);
Map<String, Object> requestContext = ((BindingProvider)sayHello).getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://localhost:8888/webservice/helloworld?wsdl");
Map<String, List<String>> requestHeaders = new HashMap<String, List<String>>();
requestHeaders.put("username", Collections.singletonList("nikos"));
requestHeaders.put("Password", Collections.singletonList("superpassword"));
requestContext.put(MessageContext.HTTP_REQUEST_HEADERS, requestHeaders);
System.out.println(sayHello.getHelloWorldAsString("- This is Java Code Geeks"));
}
}
可能最好但最复杂的是具有各种身份验证方法的 WS-Security。 但它是最复杂的,并且有利于企业环境。 它允许您创建端到端身份验证,并且有很多选项。 您可以在简单的情况下使用Web 服务安全用户名令牌配置文件
<S12:Envelope xmlns:S11="..." xmlns:wsse="..." xmlns:wsu= "...">
<S12:Header>
...
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>NNK</wsse:Username>
<wsse:Password Type="...#PasswordDigest">weYI3nXd8LjMNVksCKFV8t3rgHh3Rw==</wsse:Password>
<wsse:Nonce>WScqanjCEAC4mQoBE07sAQ==</wsse:Nonce>
<wsu:Created>2003-07-16T01:24:32</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
...
</S12:Header>
...
</S12:Envelope>
我不知道您使用什么库,但这里有一篇不错的文章如何将 Rampart 安装到 Axis2 并实现 UsernameToken 处理。
但在某些简化的情况下,您可以简单地对 web 服务器进行 HTTP 基本身份验证(通过 SSL)。 这可能是最糟糕的解决方案,但有时可能最容易实施。 另一种解决方案,不连接 soap 可以相互认证 SSL (与客户端身份验证)。
WS-Security 提供了标准方法来保护基于 SOAP 的 web 服务,WS-Security Policy 说明了如何将这些安全要求传达给外界。
身份验证可以使用用户名/密码 - 基于 UsernameToken 或证书。
由于您是基于 Java - 您可以使用开源WSO2 应用服务器来部署您的服务,并且只需点击几下即可保护您的服务。
这进一步解释了如何做到这一点......
谢谢...
这是通过具有身份验证的 JAX-WS 的 Web 服务的一个很好的示例
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.