我试图通过其相应的wsdl使用Web服务.此服务依赖于符合Web服务安全基本安全配置文件1.0的身份验证,包括http://docs.oasis-open.org/wss/2004/01/oasis-200401wss-wssecurity-secext-1.0的正确xmls命名空间. xsd必须包含在请求中.
例:
<wsse:UsernameToken xmlns:wsse='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' >
<wsse:Username>
Bob
</wsse:Username>
<wsse:Password Type='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText'>
1234
</wsse:Password>
</wsse:UsernameToken>
Run Code Online (Sandbox Code Playgroud)
我的第一次尝试是Add Service Reference针对wsdl以及使用它们生成的代理
ServicePointManager.ServerCertificateValidationCallback =
(object s, X509Certificate certificate, X509Chain chain,
SslPolicyErrors sslPolicyErrors) => true;
var basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
basicHttpBinding.Security.Transport.ClientCredentialType =
HttpClientCredentialType.Basic;
var endpoint = new EndpointAddress("https://secure-ausomxana.crmondemand.com/..."
using (var client = new ContactClient(basicHttpBinding, endpoint))
{
var credential = client.ClientCredentials.UserName;
credential.UserName = "bob";
credential.Password = "1234";
var input = ...
var output = client.ContactQueryPage(input);
}
Run Code Online (Sandbox Code Playgroud)
但是,尝试使用Fiddler查询SOAP消息时,我发现没有添加任何UsernameToken元素.
履行这份合同的正确方法是什么?
编辑: …
我正在尝试创建类似的东西:客户端验证并从自定义STS1获取令牌,下一个客户端使用机器密钥授权并在自定义STS2上获得令牌并获取另一个令牌.使用最后一个令牌,客户端请求RP服务上的方法.
所有服务都托管在IIS上,并且正在使用活动联合方案.两个STS都有ws2007Federation和ws2007Http绑定的端点,RP使用ws2007FederationBinding和STS2作为发行者.
如果我使用CreateChannelWithIssuedToken创建通道,我只能看到来自STS1的令牌,并且无法从STS2获取令牌.
所以我决定将STS1中的令牌作为ActAs RST的属性传递给STS2令牌.那失败了 - 无法解密令牌.
最近,我们对我们的代码进行了安全审核,其中一个问题是我们的应用程序受Xml外部实体(XXE)攻击.
基本上,应用程序是一个通过Web服务以XML形式接收输入的计算器.
以下是对我们的应用程序进行此类XXE攻击的示例:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<foo:calculateStuff>
<!--Optional:-->
<xmlInput><![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE currency [
<!ENTITY include SYSTEM "file:///d:/" >]>
<calcinput>...</calcinput>
]]></xmlInput>
</foo:calculateStuff>
</soapenv:Body>
</soapenv:Envelope>
Run Code Online (Sandbox Code Playgroud)
如您所见,我们可以引用指向外部文件("file:///d:/")的实体.
关于XML输入本身(该<calcinput>...</calcinput>部分)是使用JAXB(v2.1)解组的.Web服务部分基于jaxws-rt(2.1).
我需要做些什么来保护我的网络服务?
对于与IIS托管的RESTful WCF服务进行通信的Windows窗体应用程序,实现授权/身份验证的最佳方法是什么?
我问的原因是我非常困惑,在筛选出不同的文章和帖子后表达了不同的方法并最终在WCF安全最佳实践中找到了约650页的文档"(http://www.codeplex.com/WCFSecurityGuide)我是根据我的情况,我不确定哪种方法最好采取以及如何开始实施.
我从这篇文章"使用WCF 3.5设计和构建RESTful Web服务指南"(http://msdn.microsoft.com/en-us/library/dd203052.aspx)和RESTful WCF服务的PDC视频开始很棒,帮助我实现了我的第一个REST友好的WCF服务,
在我使用该服务后,我返回实施安全性,请参阅."安全注意事项"(页面下方四分之一)并尝试按照说明实现HTTP Authorization标头,但是我发现代码不完整(请参阅"UserKeys"变量从未声明的方式).这是我试图研究如何做到这一点的更多点(使用带有"授权"HTTP标头的HMAC哈希,但在谷歌上找不到多少?)它引导我阅读有关消息级安全性的其他文章,形成auth和自定义验证器,坦率地说,我不确定哪种方法最好,最合适.
所以说了这些(感谢听到现在!),我想我的主要问题是,
- 我应该使用哪种安全实施方案?
- 有没有办法避免每次WCF呼叫都发送用户名/密码?如果在开始时建立了连接,我宁愿不发送这些额外的字节,这将是在登录后允许进行后续调用之前.
- 如果我使用SSL,我是否真的应该关注除纯文本以外的任何内容?
如上所述,.NET 3.5 win表单应用程序,IIS托管的WCF服务,但重要的是我希望任何和所有WCF服务都需要此授权程序(但它应该是,session,http header或其他),因为我不希望任何人能够从网上获得这些服务.
我知道上面的帖子很大但是我必须表达我已经失败的路线以及我需要完成的任务,我们非常感谢所有的帮助.
PS:我也知道这篇文章如何使用用户名/密码+ SSL配置WCF的安全REST服务,如果社区建议我从REST转移到WCF服务,我可以这样做,但是我开始这样做以保持一致性任何公共API来.
我认为重要的是我说明了我如何访问我的WCF服务(联系服务正在运行,但验证凭据的最佳方法是什么 - 然后返回Member对象?):
WebChannelFactory<IMemberService> cf = new WebChannelFactory<IMemberService>(
new Uri(Properties.Settings.Default.MemberServiceEndpoint));
IMemberService channel = cf.CreateChannel();
Member m = channel.GetMember("user", "pass");
Run Code Online (Sandbox Code Playgroud)
代码是MS文章中的一半(以及我自己的一些用于测试):
public Member GetMember(string username, string password)
{
if (string.IsNullOrEmpty(username))
throw new WebProtocolException(HttpStatusCode.BadRequest, "Username must be provided.", null);
if (string.IsNullOrEmpty(password))
throw new WebProtocolException(HttpStatusCode.BadRequest, "Password must be provided.", null);
if (!AuthenticateMember(username))
{
WebOperationContext.Current.OutgoingResponse.StatusCode …Run Code Online (Sandbox Code Playgroud) 我正在尝试连接到受密码保护且网址为https的Web服务.在脚本发出请求之前,我无法弄清楚如何进行身份验证.它似乎在我定义服务时立即发出请求.例如,如果我投入:
$client = new SoapClient("https://example.com/WSDL/nameofservice",
array('trace' => 1,)
);
Run Code Online (Sandbox Code Playgroud)
然后在浏览器上访问该站点,我得到:
Fatal error: Uncaught SoapFault exception:
[WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from
'https://example.com/WSDL/nameofservice' in /path/to/my/script/myscript.php:2
Stack trace: #0 /path/to/my/script/myscript.php(2):
SoapClient->SoapClient('https://example...', Array) #1 {main} thrown in
/path/to/my/script/myscript.php on line 2
Run Code Online (Sandbox Code Playgroud)
如果我尝试将服务定义为Soap服务器,例如:
$server= new SoapServer("https://example.com/WSDL/nameofservice");
Run Code Online (Sandbox Code Playgroud)
我明白了:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>WSDL</faultcode>
<faultstring>
SOAP-ERROR: Parsing WSDL:
Couldn't load from 'https://example.com/WSDL/nameofservice'
</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Run Code Online (Sandbox Code Playgroud)
我还没有尝试发送原始请求信封,看看服务器返回什么,但这可能是一种解决方法.但是我希望有人可以告诉我如何使用php内置类来设置它.我尝试将"userName"和"password"添加到数组中,但这并不好.问题是我甚至无法判断我是否到达了远程站点,更不用说它是否拒绝了请求.
我正在尝试创建一个独立的客户端来使用一些Web服务.我必须将我的用户名和密码添加到SOAP Header中.我尝试添加凭据如下:
OTSWebSvcsService service = new OTSWebSvcsService();
OTSWebSvcs port = service.getOTSWebSvcs();
BindingProvider prov = (BindingProvider)port;
prov.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "myusername");
prov.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "mypassword");
...
Run Code Online (Sandbox Code Playgroud)
当我在服务上调用方法时,我得到以下异常:
com.ibm.wsspi.wssecurity.SoapSecurityException: WSEC5048E: One of "SOAP Header" elements required.
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我如何将这些属性添加到SOAP标头?
编辑:我使用的是JDK6中包含的JAX-WS 2.1.我现在正在使用JAX-WS 2.2.我现在得到以下异常:
com.ibm.wsspi.wssecurity.SoapSecurityException: WSEC5509E: A security token whose type is [http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken] is required.
Run Code Online (Sandbox Code Playgroud)
我该如何创建此令牌?
我试着从KeyStore获取Key.我用Keytool创建了一个密钥库:
keytool -genkeypair -dname"cn = Mark Jones,ou = JavaSoft,o = Sun,c = US"-alias business2 -keypass abcdtest -keystore C:\ workspace\XMLSample\keystore\mykeystore.jks -storepass 123456
以下是GenerateXML.java
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import javax.xml.crypto.dsig.XMLSignContext;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
public class GenerateXML {
public static void main(String[] args) throws Exception {
try {
char[] passwd = "123456".toCharArray();
//Load the KeyStore and get the signing key and certificate
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("C:\\workspace\\XMLSample\\keystore\\mykeystore.jks"), passwd);
KeyStore.PrivateKeyEntry keyEnt = (KeyStore.PrivateKeyEntry)ks.getEntry("business2", new KeyStore.PasswordProtection(passwd)); // …Run Code Online (Sandbox Code Playgroud) 我需要创建一个wcf客户端来调用我无法控制的服务.
我得到了一个wsdl和一个有效的soapui项目.
该服务使用用户名/密码和x509证书.
UPDATE
我现在明白问题是什么,但我仍然不确定我需要采取哪些步骤来创建所需的消息,所以任何帮助都将非常感激.
我需要同时签署UsernameToken和SecurityTokenReference.
由于不再使用,我必须从此帖子中删除我必须创建自定义绑定的代码.我不再向绑定添加SecurityBindingElement,而是添加了一个将安全元素写入标头的新行为.
因此,通过继承SignedXml类,添加签名引用然后调用ComputeSignature以在Security头中创建Signature节点,从头开始创建安全节点.
您需要传递xml以登录SignedXml构造函数才能使其生效.传递UsernameToken没问题,这似乎是正确签名的.
问题是SecurityTokenReference仅在调用ComputeSignature()时创建,因此我无法为此元素添加签名引用,因为它在需要时不存在(在SignedXml的重写的GetIdElement方法中)在ComputeSignature()之前调用的)
我用来创建要插入Security头的签名块的代码如下
string certificatePath = System.Windows.Forms.Application.StartupPath + "\\" + "Certs\\sign-and- enc.p12";
XmlDocument xd = new XmlDocument();
xd.LoadXml(xml);
// Set Certificate
System.Security.Cryptography.X509Certificates.X509Certificate2 cert = new X509Certificate2(certificatePath, "password");
MySignedXml signedXml = new MySignedXml(xd);
signedXml.SigningKey = cert.PrivateKey;
// Create a new KeyInfo object.
KeyInfo keyInfo = new KeyInfo();
keyInfo.Id = "";
MemoryStream keyInfoStream = new MemoryStream();
XmlWriter keyInfoWriter = XmlWriter.Create(keyInfoStream);
WSSecurityTokenSerializer.DefaultInstance.WriteKeyIdentifierClause(keyInfoWriter, new LocalIdKeyIdentifierClause("token_reference", typeof(X509SecurityToken)));
keyInfoWriter.Flush();
keyInfoStream.Position = 0;
XmlDocument keyInfoDocument = new XmlDocument();
keyInfoDocument.Load(keyInfoStream); …Run Code Online (Sandbox Code Playgroud) 我需要从Java调用用.NET编写的Web服务.Web服务实现了WS-Security堆栈(WSE 2或WSE 3,从我的信息中不清楚).
我从服务提供商处收到的信息包括WSDL,policyCache.config文件,一些示例C#代码以及可以成功调用服务的示例应用程序.
这听起来没那么有用,因为我不清楚我应该如何使用这些信息来编写Java客户端.如果Web服务请求未根据策略签名,则服务将拒绝该服务请求.我正在尝试使用Apache Axis2,我找不到任何有关如何使用policyCahce.config文件和WSDL来生成客户端的说明.
我在网上找到了几个例子,但在所有情况下,示例的作者都控制了服务和客户端,因此能够对双方进行调整以使其工作.我不在那个位置.
有人做过这个吗?
Soap UI具有以下选项"使用单个证书进行签名"

什么是相应的spring-ws配置?
