My wsdl says Asymmetric Binding. Initiator Token and Receipienct TokenHow can I generate a binary security token for both client and server. Can I implement with kind of security with only one private key.
.
Here is the wsdl
<sp:AsymmetricBinding>
<wsp:Policy>
<wsp:ExactlyOne><wsp:All><sp:InitiatorToken><wsp:Policy><wsp:ExactlyOne>
<wsp:All><sp:X509Token><wsp:Policy>
<wsp:ExactlyOne><wsp:All><sp:WssX509V3Token11/></wsp:All>
</wsp:ExactlyOne>
</wsp:Policy></sp:X509Token></wsp:All>
</wsp:ExactlyOne></wsp:Policy></sp:InitiatorToken>
<sp:RecipientToken><wsp:Policy><wsp:ExactlyOne><wsp:All><sp:X509Token><wsp:Policy><wsp:ExactlyOne><wsp:All>
<sp:WssX509V3Token11/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
</sp:X509Token>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy></sp:RecipientToken>
<sp:AlgorithmSuite><wsp:Policy><wsp:ExactlyOne><wsp:All><sp:TripleDesRsa15/></wsp:All></wsp:ExactlyOne></wsp:Policy>
</sp:AlgorithmSuite>
</wsp:All></wsp:ExactlyOne
></wsp:Policy>
</sp:AsymmetricBinding>
In case I make a custom binding with security element like this .
`var sec = `(AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
I was able to genrte Username token with none. This was the security element
var security = TransportSecurityBindingElement.CreateUserNameOverTransportBindingElement();
The Sample soap request uses these terms to describe the binary security tokens
....(eMedNY signed user MLS cert).....
.....( eMedNY MLS web-service end-point public cert).........
...nonce,.
I have the private key for the former. But does the server one need a private key?.. It is a public certificate. What should be the security element. Do I need two security elements. One for the binary security token and one for usernametoken.?
Thank u
Related
I am consuming one service which only establishes the connection over TLSv1.2 protocol.
In SoapUI
-Dsoapui.https.protocols=TLSv1.2 :- This parameter works fine and able to get the response from the service in SOAP UI tool.
Need something similiar like above parameter on the mule ESB flow which allows my request to use TLSv1.2 protocol explicitly during proxing.
I am using Mule 3.7 CE & JDK 7. The message flow uses CXF proxies(cxf:proxy-service) to direct SOAP based requests over Https to the end client. When a request is sent to Mule it is throwing an exception as below.
Caused by: org.apache.cxf.ws.policy.PolicyException: These policy alternatives can not be satisfied: {http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}TransportBinding: TLS is not enabled {http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}HttpsToken {http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702}TransportToken at org.apache.cxf.ws.policy.AssertionInfoMap.checkEffectivePolicy(AssertionInfoMap.java:179) ~[cxf-rt-ws-policy-2.7.15.jar:2.7.15]
Already tried enabling protocol through tls-default.conf file also adding system arguments and server arguments did not work.
Here is the snippet of wsdl using security policy -
<wsp:Policy wsu:Id="XYSPolicyID">
<wsp:ExactlyOne>
<wsp:All>
<sp:TransportBinding
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:TransportToken>
<wsp:Policy>
<sp:HttpsToken RequireClientCertificate="false" />
</wsp:Policy>
</sp:TransportToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256 />
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict />
</wsp:Policy>
</sp:Layout>
</wsp:Policy>
</sp:TransportBinding>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
Any help would be much appreciated !!
You can configure your cryptographic protocols and cipher suites I'm MULE_HOME/tls-default.conf
As stated in the previous reply, enabledProtocols=TLSv1.2 should do the trick.
If you continue having problems, you can use the following to troubleshoot:
Start Mule with the following flag -M-Djavax.net.debug=ssl:handshake:verbose
In that way you will be able to see the actual handshake process.
Another useful tool is TestSSLServer to determine supported protocols and cipher suites of the target system.
Also, you may consider installing the Java Cryptography Extension package.
HTH, Nahuel.
I try to access a java-webservice which uses ws-security (wsse). I tried to consume it using svcutil:
svcutil *.wsdl *.xsd /language:C# /tcv:Version35
This works well, but I get an error importing this block in wsdl-file
<wsp:Policy wsu:Id="myServiceRequestResponseSoapBindingPolicy" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsp:ExactlyOne>
<wsp:All>
<sp:SupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:WssUsernameToken11/>
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
saying
An unsupported security policy assertion was detected
So this gets ignored.
As you may expect communicating with the service returns an error saying "unauthorized". The information I got from the webservice owner pointed out that my message contains no WSSecurity-part.
I found this thread svcutil getting stuck on usernameToken Policy but the policy seems to differ because I don't have any certificate. So I don't get anywhere on this path.
I installed WSE3 cos I had the impression I'd need it for something, but I'm quite unsure now if this is the case and how this needs to interact with my wcf-client.
Any suggestions appreciated, thank you.
Don't worry about that warning, the WSDL section is not relevant (you can even remove it). What you should have is a sample working SOAP request from a wroking client (e.g. Java) or from a sample of the vendor, with the security in it. Then you can configure your binding to support it. Just from the WSDL section you published you might want to try basicHttpBinding with security mode of TransportWithMessageCredential.
Googling for wcf and usernametoken brought me to this solution - it's so easy if you get the right search words...
http://weblog.west-wind.com/posts/2012/Nov/24/WCF-WSSecurity-and-WSE-Nonce-Authentication
I am trying to connect to tomcat with an active directory user.
When the password is in plain text like the following:
<Realm className="org.apache.catalina.realm.JNDIRealm"
connectionURL="ldap://localhost:389"
connectionName="user_name"
connectionPassword="password"
userBase="OU=blabla,DC=aaa,DC=com"
userSubtree="true"
userSearch="(sAMAccountName={0})"
userRoleName="memberOf"
roleBase="OU=blabla,DC=aaa,DC=com"
roleName="cn"
roleSubtree="true"
roleSearch="(member={0})" />
the authentication is ok. BUT, I don't want a password in my configuration file.
I tried the following:
<Realm className="org.apache.catalina.realm.JNDIRealm"
connectionURL="ldap://localhost:389"
digest="MD5"
connectionName="user_name"
connectionPassword="encrypted_password"
userBase="OU=blabla,DC=aaa,DC=com"
userSubtree="true"
userSearch="(sAMAccountName={0})"
userRoleName="memberOf"
roleBase="OU=blabla,DC=aaa,DC=com"
roleName="cn"
roleSubtree="true"
roleSearch="(member={0})" />
but the authentication fails.
I didn't find any solution.
I will really appreciate any help
thank you
I think your only alternative is to subclass JNDIRealm and make a new attribute that will have some sort of encrypted connection password. The password can't be hashed (with, e.g. MD5 as you specify) because hashes are one-way--there's no undoing a hash--and Tomcat needs the password in its original unhashed form to authenticate against the AD installation.
If you use a reversible encryption in your JNDIRealm subclass, then when Tomcat needs the password you can decrypt the password and pass it along.
My particular problem is something like this:
We are currently running a set of services which requires the clients to provide a username and password as authentication when calling the services.
We would like to implement a PKI-infrastructure on these services, but some of our partners will use longer time to accommodate to this new infrastructure than the others.
As a first step we want to require client certificates from some of our partners. A client certificate will be required (in addition to username and password) to access their data on our servers, while for the other users only username and password will be required.
To solve this problem I am trying to implement a custom validator for both the username/password authentication (using UserNamePasswordValidator) and for the client certificates (using X509CertificateValidator) in WCF. The username/password validator will verify these credentials towards our database, while the client certificate validator will inspect whether the request is from a client from which we require a certificate, and if so verify that a valid client certificate is provided. I have not been able to configure WCF so that it uses both of these validators.
My WCF configuration on the server is currently set up like this:
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpsGetEnabled="true" policyVersion="Policy15" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<clientCertificate>
<authentication customCertificateValidatorType="MyWS.Security.MyServicesCertificateValidator, MyWS"
certificateValidationMode="Custom" revocationMode="NoCheck" />
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="MyWS.Security.MyServicesUsernameValidator, MyWS" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
<bindings>
<basicHttpBinding>
<binding name="MySoapBinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate" />
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="MyServiceBehavior" name="MyWS.Services.TheService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="MySoapBinding" name="TheService" bindingNamespace="https://services.my/TheService" contract="MyWS.Interfaces.Service.ITheService" />
<host>
<baseAddresses>
<add baseAddress="https://localhost:4434/MyWS/TheService"/>
</baseAddresses>
</host>
</service>
</services>
As far as I understand this configuration is invalid because I can't use the customCertificateValidatorType at the transport layer (because IIS inspects the certificate before WCF is involved here), but I can not see how I am able to combine both the customCertificateValidatorType and customUserNamePasswordValidatorType as credential types at the message layer either.
I have implemented a message inspector and might be able to solve the problem using the OperationContext in some way (as suggested in the link below), but I have not been able to see a way for me to do it this way yet.
http://social.msdn.microsoft.com/Forums/en/wcf/thread/b6ab8b58-516b-41d4-bb0e-75b4baf92716
I suppose I might be trying to implement something that is incompatible with the way WCF works, but if someone have an idea about how this could be fixed I would be delighted to have your feedback on this.
I think I have found a solution to my problem now thanks to valuable input from #ladislav-mrnka in his answer. I realized it is necessary to provide two endpoints to configure the different requirements, and I also learned about the supporting token possibilities when configuring the services.
I found a link about supporting tokens at MSDN, and by following this recipe I have implemented the endpoint on the server with the following custom binding (I switched to configuration through code. Not sure if this can be set up in web.config as well.)
private static Binding CreateMultiFactorAuthenticationBinding()
{
var httpsTransport = new HttpsTransportBindingElement();
// The message security binding element will be configured to require 2 tokens:
// 1) A username-password encrypted with the service token
// 2) A client certificate used to sign the message
// Create symmetric security binding element with encrypted username-password token.
// Symmetric key is encrypted with server certificate.
var messageSecurity = SecurityBindingElement.CreateUserNameForCertificateBindingElement();
messageSecurity.AllowInsecureTransport = false;
// Require client certificate as endorsing supporting token for all requests from client to server
var clientX509SupportingTokenParameters = new X509SecurityTokenParameters
{
InclusionMode =
SecurityTokenInclusionMode.AlwaysToRecipient
};
messageSecurity.EndpointSupportingTokenParameters.Endorsing.Add(clientX509SupportingTokenParameters);
return new CustomBinding(messageSecurity, httpsTransport);
}
This binding creates a SymmetricSecurityBindingElement where a symmetric key (encrypted with the server certificate) is used to encrypt a username/password security token in the message header, and the message body itself.
In addition a X509 security token is added as an endorsing, supporting token to the binding. This token is configured to always be included in the client requests to the server.
This custom binding was subsequently used to configure a new WCF-service with an endpoint requiring this binding. I am using the WcfFacility in Castle Windsor to configure the service.
This code does the following:
Sets the service certificate
Sets the validation mode for the client certificates to chain trust, so that incoming client certificates must be issued by a trusted root certificate authority in the server store
Adds custom validators for username/password credentials and client certificate
//// Registering WCF-services
var returnFaults = new ServiceDebugBehavior {IncludeExceptionDetailInFaults = true};
var metaData = new ServiceMetadataBehavior {HttpsGetEnabled = true};
var serviceCredentials = new ServiceCredentials();
// Configure service sertificate
serviceCredentials.ServiceCertificate.SetCertificate(
StoreLocation.LocalMachine,
StoreName.My,
X509FindType.FindBySubjectName,
"ServerCertificate");
// Configure client certificate authentication mode
serviceCredentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.ChainTrust;
// Add custom username-password validator
serviceCredentials.UserNameAuthentication.UserNamePasswordValidationMode =
UserNamePasswordValidationMode.Custom;
serviceCredentials.UserNameAuthentication.CustomUserNamePasswordValidator =
_container.Resolve<MyServicesUsernameValidator>();
// Add custom certificate validator
serviceCredentials.ClientCertificate.Authentication.CertificateValidationMode =
X509CertificateValidationMode.Custom;
serviceCredentials.ClientCertificate.Authentication.CustomCertificateValidator =
_container.Resolve<MyServicesCertificateValidator>();
var serviceModel = new DefaultServiceModel();
serviceModel.AddEndpoints(
WcfEndpoint.ForContract<IMyContract>().BoundTo(CreateMultiFactorAuthenticationBinding()));
serviceModel.BaseAddresses.Add(new Uri("https://server.com/MyServiceImplementation.svc"));
serviceModel.AddExtensions(serviceCredentials);
serviceModel.AddExtensions(metaData);
_container.AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero)
.Register(Component.For<IMyContract>()
.ImplementedBy<MyServiceImplementation>()
.AsWcfService(serviceModel),
Component.For<IServiceBehavior>().Instance(returnFaults));
MyServicesUsernameValidator inherits UserNamePasswordValidator and MyServicesCertificateValidator inherits X509CertificateValidator. Both overrides their corresponding Validate methods.
This seems to solve my particular problem... Hope it solves yours! :)
That is not possible to define in configuration with out of the box bindings. Even custom binding doesn't support enough infrastructure to define such binding in configuration.
First you will definitely need two endpoints for this. One will be used for clients with user name / password only. This endpoint can be configured with some common binding expecting either Message security with UserName client credentials or transport security with message credentials. The second endpoint will be for your more complex validation. This endpoint needs new binding defined in code. This binding must use:
Asymetric security binding element (mutual certificate authentication)
X.509 security token as primary security token
User name security token as supporting security token
This is example of the binding I had to use when communicating with similar service:
Custom binding = new CustomBinding();
var userNameToken = new UserNameSecurityTokenParameters();
userNameToken.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
var securityElement = new AsymmetricSecurityBindingElement();
securityElement.IncludeTimestamp = true;
securityElement.RecipientTokenParameters = new X509SecurityTokenParameters(X509KeyIdentifierClauseType.SubjectKeyIdentifier, SecurityTokenInclusionMode.Never);
securityElement.InitiatorTokenParameters = new X509SecurityTokenParameters(X509KeyIdentifierClauseType.SubjectKeyIdentifier, SecurityTokenInclusionMode.AlwaysToRecipient);
securityElement.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256;
securityElement.SecurityHeaderLayout = SecurityHeaderLayout.Strict;
securityElement.SetKeyDerivation(false);
securityElement.EndpointSupportingTokenParameters.SignedEncrypted.Add(userNameToken);
securityElement.MessageProtectionOrder = MessageProtectionOrder.EncryptBeforeSign;
securityElement.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11;
binding.Elements.Add(securityElement);
var encodingElement = new TextMessageEncodingBindingElement();
encodingElement.MessageVersion = MessageVersion.Soap12WSAddressingAugust2004;
binding.Elements.Add(encodingElement);
var httpElement = new HttpTransportBindingElement();
httpElement.UseDefaultWebProxy = true;
binding.Elements.Add(httpElement);
This example uses CustomBinding defined in code. If you want to use this in configuration you must create whole new binding and binding extension and register that extension in configuration file.
Even then I'm not sure that both validators will be used - I used this as the client of the service. The main point is that request can have only single main token and it is possible that default WCF infrastructure will choose only one to validate but such logic can be also replaced.
Scenario: I am writing a WCF client to access a Java/Metro webservice which requires several SOAP headers to be signed and encrypted:
<wsp:Policy>
<wsp:ExactlyOne>
<wsp:All>
<sp:SignedParts>
<sp:Body/>
<sp:Header Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Namespace="... application specific headers ..."/>
</sp:SignedParts>
<sp:EncryptedParts>
<sp:Header Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Namespace="... application specific headers ..."/>
</sp:EncryptedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
It works for the application specific headers (the ProtectionLevel attribute is applied on the respective proxy type members). The WS-Addressing headers, however, are signed but not encrypted.
I tried to add them programmatically to the ChannelProtectionRequirements message parts collection(s) through contract or endpoint behaviors (e.g. like described here). No success.
Any ideas how to do this?
Ok, sackcloth & ashes coming up. I'm not sure what went wrong in my tests, but it does work when I add the respective headers to the IncomingSignatureParts and IncomingEncryptionParts of the service endpoint through a contract behavior.