I am updating a web service application written in VS2012 in C# in which I would like to get the client application name.
Is there a system calls that I can make to get this value?
Originally, in the web service application had the following line of code:
string ApplicationID =
System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity.Name;
This .Name value returns the user's name and I need the client application name.
How can I, securely, get the client's application name?
UPDATE: It seems like the ClientCredential class can be used to set a user name like:
service1.ClientCredentials.UserName.UserName = "ClientTestApp";
in the client application and you can access the the user name in the web service application using:
string TestAppName = System.ServiceModel.ServiceSecurityContext.Current.PrimaryIdentity.Name;
How should the binding for the endpoint be configured?
UPDATE:
To give an example of what I mean in the comment below...
CLIENT APPLICATION:
Service1.ClientCredentials.UserName.UserName = "ClientAppName";
try
{
Service1.Method1(ProfileID, OrderID);
}
catch (Exception ex)
{
string Error = ex.Message;
}
WEB SERVICE METHOD:
public void Method1(long ProfileID, int OrderID)
{
//The ApplicationID will be "ClientAppName"
string ApplicationID = ServiceSecurityContext.Current.PrimaryIdentity.Name;
try
{
//CHeck the ApplicationID and do stuff...
}
}
Configuration File The binding will probably have to include a Credential of UserName. But I can't seem to get the correct configuration to get this to work.
Is what I am describing possible?
UPDATE
I have read a lot about setting the configuration file with these security elements and attributes. But I am still learning. So I apologize, in advance, for asking some basic questions.
I got a value assigned to the ApplicationID in the web service application:
string ApplicationID = ServiceSecurityContext.Current.PrimaryIdentity.Name;
by using this binding configuration:
<wsHttpBinding>
<binding name="ServiceEndpoint" closeTimeout="00:01:00">
<security mode="Message">
</security>
</binding>
</wsHttpBinding>
However, the value stored in
ServiceSecurityContext.Current.PrimaryIdentity.Name;
is my User Name for Windows Authentication in my SQL Server 2012 Management Studio.
According to the documentation the ServiceSecurityContext class should return the following: "Represents the security context of a remote party. On the client, represents the service identity and, on the service, represents the client identity."
How is it getting this user name value?
Is there anyway I can set it with another value?
By using wsHttpBinding and the Message attribute, does this mean it is using the SOAP message security? (The body is encrypted and signed.)
TRYING ANOTHER APPROACH If I set the ClientCredentials.UserName.UserName = "TestClient" ClientCredentials.UserName.Password = "some password" In the client test application.
Add UserNamePasswordValidator class and override the Validate() method. Within this method, it checks a table in a database for the username and password.
My current configuration file with wsHttpBinding is this:
<wsHttpBinding>
<binding name="PaymentSecureServiceEndpoint" closeTimeout="00:01:00">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
When I try to update the service reference, I get the error: 'The Service certificate is not provided. Specify a service certificate in ServerCredentials.'
Is there any way I can use the validate() method without providing a service certificate? Does the ServerCredentials have to be at the service level, can it be at the endpoint level? Will this set the PrimaryIdentity.Name value to the UserName that I set in the client application?
Thanks...as always.
ADDING SELF-SIGNED CERTIFICATE
The name of my self-signed certificate is: TestCert. The location I put the certificate is: Console Root / Certificates (Local Computer) / Personal / Certificates.
This is the service behavior defined in the web.config file:
<behavior name="SecureBehavior">
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="Service1.Service1UsernamePasswordValidator, Service1"/>
<serviceCertificate findValue="TestCert" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
I get the error that it cannot find my x.509 Certificate. What did I do wrong on the serviceCertificate attributes?
UPDATE TO GETTING THE SERVICE CERTIFICATE TO BE ACCEPTED BY THE CLIENT WHEN UPDATING THE SERVICE REFERENCE I still get the error that if cannot find the certificate, even if I trying using the serial number. Below are the details of my errors:
I have a self-signed certificate in the folder of 'Certificates' under the folder 'Personal'. The 'Friendly Name' is 'TestCert'. The serial number is a hexidecimal number that starts ' 7f 79 8a a7...'. The certificate is on my local machine.
The attributes that I have tried:
storeLocation="LocalMachine" - I have not changed this. The certificate is on my local machine and all of the documentation states that when it is, this is the value that it should be.
storeName="My" - The certificate is in the 'Personal' folder in the 'Certificate' folder. This should correspond to 'My'. I guess it would be too intuitive to call it 'Personal'.
x509FindType="FindBySubjectName" - I have kept this value as '..SubjectName' when the 'findValue' was the name of the certificate. The 'Friendly Name' of the certificate is 'TestCert'. There is no option for 'FriendlyName' but I have tried 'By...DistinguishedName', 'By...TemplateName'. I have also set the option to 'FindBySerialNumber'
findValue="" - I have used the certificate name 'TestCert' and 'CN=TestCert' I have a tried copying the serial number and set the x509FindType option to search by SerialNumber but I get the error: 'Invalid hexidecimal string format'.
Why is this so difficult? There is 2 certificates in my Personal folder, one - localhost and one - 'TestCert'. It should not be that difficult to find it.
Is the problem that it is a self-signed certificate? Is it not a x509 certificate? How do I check if it is, it is not in the properties list.
No wonder security is so difficult! The documentation is bad and following the instructions do not work.