Reputation: 21
I have to Create a WCF service (ServiceWrapper), which references another WCF Service(RealService).
I want Clients of ServiceWrapper to pass Username/password in authentication request.
The Operations of ServiceWrapper Call RealService. I need to pass the recieved Username/passowrd to Authenticate with RealSerivce and then call its Operations.
I need to host the service on Http and not Https(SSL/TLS).
Question: How to use the Client Credentails Recieved by a Service to authenticate with a Referenced Service without using Https(SSL/TLS)?
Upvotes: 1
Views: 2465
Reputation: 2358
Your can use SOAP security. There are two SecurityModes for you - Message, TransportWithMessageCredential.
You should configure security mode (UserName) in <binding>
section like this
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="" />
<message clientCredentialType="UserName" />
</security>
Next, you should specify custom validator in <behavior>
section
<behavior name="CommonBehavior">
<serviceMetadata />
<serviceDebug includeExceptionDetailInFaults="True"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="Megatec.MasterTourService.CustomUserNameValidator, Megatec.MasterTourService"/>
<serviceCertificate findValue="WCFServer" storeLocation="LocalMachine"
storeName="My" x509FindType="FindBySubjectName"/>
<clientCertificate>
<authentication certificateValidationMode="PeerTrust" />
</clientCertificate>
</serviceCredentials>
</behavior>
In your custom validator you can access and store user name and password, which were given as creditionals for ServiceWrapper.
using System.ServiceModel;
using System.IdentityModel.Selectors;
namespace MyService
{
public class CustomUserNameValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (!(userName == "testMan" && password == "pass"))
throw new FaultException("Incorrect login or password");
// save your Usermame and Password for future usage.
}
}
}
When you need to access RealService, you can use userName and password as credentials, like my example below:
private readonly Dictionary<Type, Object> channelFactoryDictionary = new Dictionary<Type, Object>();
private ChannelFactory<T> GetChannelFactory<T>() where T : class
{
if (channelFactoryDictionary.Keys.Contains(typeof(T)))
return channelFactoryDictionary[typeof(T)] as ChannelFactory<T>;
var channelFactory = new ChannelFactory<T>("*");
channelFactory.Credentials.UserName.UserName = userName;
channelFactory.Credentials.UserName.Password = password;
channelFactoryDictionary.Add(typeof(T), channelFactory);
return channelFactory;
}
Upvotes: 3
Reputation: 8880
If SSL is not an option, you will need to use SOAP message security (SecurityMode = Message).
http://msdn.microsoft.com/en-us/library/ms733137.aspx
Upvotes: 1