WCF Service Error: At least one security token in the message could not be validated

Hello,

I have a webservice that I,m trying to apply a custome security, when I try to call the service it display the following error:


http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:FailedAuthentication

At least one security token in the message could not be validated.


To add the security I modify the service config file:

[b][b]<services> <service name = "WcfService1.Service1"> <endpoint address="" binding="customBinding" bindingConfiguration="customBindingOasis" contract="WcfService1.IService1"> <headers> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsse:UsernameToken> <wsse:Username>USERNAME</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">PASSWORD</wsse:Password> </wsse:UsernameToken> </wsse:Security> </headers> </endpoint> </service> </services> <bindings> <customBinding> <binding name ="customBindingOasis"> <security authenticationMode="UserNameOverTransport" includeTimestamp="false" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"> <secureConversationBootstrap /> </security> <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" messageVersion="Soap12" writeEncoding="utf-8"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> </textMessageEncoding> <httpsTransport manualAddressing="false" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous" realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false" useDefaultWebProxy="true" requireClientCertificate="false" /> </binding> </customBinding> </bindings> <protocolMapping> <remove scheme ="https"/> <add binding="customBinding" scheme ="https"/> </protocolMapping> [/b][/b]

I suppose that the error is because I,m not sending back and Answer telling that the token is good.

The question is: How I can get the send token in the request and validate it in my service and return it like good or bad? not the function to validate the token, only how to make a get of the token in my code and send the response back.
Jose CollazoAsked:
Who is Participating?
 
Dan McFaddenConnect With a Mentor Systems EngineerCommented:
This article presents basic code for using credentials passed to a WCF web service.

Link:  https://www.rhyous.com/2015/02/05/basic-token-service-for-wcf-services-part-1/

Also, the link I postedx to Rick Stahl's Web Log also makes reference to using the submitted credentials.

Something similar to:

var client = new RealTimeOnlineClient();

client.ClientCredentials.UserName.UserName = "TheUsername";
client.ClientCredentials.UserName.Password = "ThePassword";

Open in new window


Dan
0
 
Dan McFaddenSystems EngineerCommented:
Didn't you ask a similar question about this topic?

Q:  https://www.experts-exchange.com/questions/29073350/C-2015-web-service-oasis-usernametoken.html

I believe the links there cover implementing OASIS Auth in a WCF Service.

Dan
0
 
Jose CollazoAuthor Commented:
Thanks Dan,


I,m really new to this security options in c# and wcf, What I dont undestarnd is how I can capture the values submited in the soap header and respond with a valid or false answer.

I will be receiving the following header in the request.

<soapenv:Header>
<wsse:Securityxmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"soapenv:mustUnderstand="true">
<wsse:UsernameTokenxmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"wsu:Id="UsernameToken-21621664">
<wsse:Username>bob</wsse:Username>
<wsse:PasswordType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bobPW</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>

How I can get the username and passwordtext that are in the header and pass them to my code  and how I can return a faild when there are not correct?

I know how to validate if the token is good, but need to get the values to my function.

Do you have any generic code that I can use as an example?

Thanks for the help.
0
 
Jose CollazoAuthor Commented:
Hello,

I was able to validate the user credential.

Here are what i did.

1. Create a custom binding in the web.config:

<customBinding>
        <binding name="mycustomBinding" closeTimeout="00:02:00" openTimeout="00:02:00"
          receiveTimeout="00:10:00" sendTimeout="00:02:00">
          <security authenticationMode="UserNameOverTransport" includeTimestamp="false"
            messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
            <secureConversationBootstrap />
          </security>
          <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
            messageVersion="Soap12" writeEncoding="utf-8">
            <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          </textMessageEncoding>
          <httpsTransport manualAddressing="false" maxBufferPoolSize="524288"
            maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
            bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
            realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
            useDefaultWebProxy="true" requireClientCertificate="false" />
        </binding>
      </customBinding>

Open in new window


The security authenticationMode have to be set to "UserNameOverTransport" and the  messageSecurityVersion have to be set to "WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"

2. Create a Service Authenticator class. The following is a basic example that should not be used in producction, create your own class.

public class ServiceAuthenticator:UserNamePasswordValidator

    {


        public override void Validate(string Username, string Password)
        {
            if (null == Username || null == Password)
            {
                throw new ArgumentNullException();
            }

            if (!(Username == "test" && Password == "test"))
            {
                throw new SecurityTokenException("Unknown Username or Password");
            }

        }

Open in new window


3. Add a service behavior to the web.config

<behaviors>
      <serviceBehaviors>
        <behavior name ="myBehavior">
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
            <serviceCredentials >
              <userNameAuthentication  userNamePasswordValidationMode ="Custom"  
              customUserNamePasswordValidatorType="MyService.Common.ServiceAuthenticator, MyService"></userNameAuthentication>
          </serviceCredentials> 
      </behavior>
      </serviceBehaviors>
  </behaviors>

Open in new window

4. Configure your service in the Web.config

<service name="MyService" behaviorConfiguration ="MyBehavior">
      <endpoint address="" binding="customBinding" bindingConfiguration="MyBinding"
      contract="YOUR SERVICE CONTRACT">

Open in new window


With that set a user "test" with the password "test" should be able to call the service. Using Passwordtext, if your using passwordtext use a ssl certificate.
0
 
Dan McFaddenSystems EngineerCommented:
So I guess the links posted helped?

Glad you got it working.

Dan
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.