Matt_


Hi.

Can a wcf service authenticate clients with different security tokens on the same endpoint

Example: The same service authenticates a client that sends a UsernameToken, and authenticates another client sending a Kerberos ticket.

If so, what I'm trying to do is to extend a little the CustomToken wcf sample (CreditCardToken) to also authenticate clients that sends a username/password against the SqlMembershipProvider. I know I can extend the token and add a switch to know wich kind of authentication to use in the SecurityTokenAuthenticator, but I don't know if that is the better way...

And can the CustomToken sample be configured from the web.config instead of configuring it programmatically, since it uses a CustomBinding

Any help would be appreciated. Thanks in advance,

Matias.



Re: Authenticate several security tokens with the same service

Juan Wajnerman


I had the same problem before and what I did is create different endpoints for each authentication method, inside the same service:

<services>

<service name="Your.Service" behaviorConfiguration="YourServiceBehavior">

<endpoint address="windows" binding="wsHttpBinding" bindingConfiguration="WindowsAuthBinding" contract="Your.IService" />

<endpoint address="username" binding="wsHttpBinding" bindingConfiguration="UserNameAuthBinding" contract="Your.IService" />

</service>

</services>

The bindings will contain different credential types. There is no problem merging the configurations for the behaviors.

Of course, now to hit the service you need to append "/windows" or "/username" to the service address (ie: http://localhost/.../YourService.svc/username).

Hope you find this useful,

Juan





Re: Authenticate several security tokens with the same service

Matt_

Thanks for replying, Juan.

Actually, I've been able to make it work with wcf default credentials. The problem is that the CustomToken sample uses a CustomBinding, and when I try to create a wsHttpBinding via web.config, it tells me that if I configure two listen uris with the same address they must be of the same binding type (don't have the exact exception message rigth now, i'll edit and post it later).

So the problem is with that CustomBinding... Right now, I've added a switch to my custom token, a property that tells me what type of authentication to make, but I would like to be able to use WCF default tokens besides a custom one, instead of having a custom token that represents them all...

Thanks,

Matias






Re: Authenticate several security tokens with the same service

Juan Wajnerman

Can you provide an example of your service configuration in the web.config

Keep in mind that the second endpoint must have a different address. That's why I added the "address" attribute in the endpoints. That address is relative to the service base address. Of course, you can left one of the endpoints with the default and add the relative address only in the second one.

Thanks,

Juan





Re: Authenticate several security tokens with the same service

Matt_

Ok... I've been playing some more with this, and again reached a dead-end... I'll post the code of how I'm creating the ServiceHost and how do I add the endpoint using the CustomBinding and the web.config that creates the endpoint using the username token over.

First, this is the .svc file that points to the ServiceFactory:

Now, the creation of the service host:

Code Snippet

using System;

using System.Collections.Generic;

using System.ServiceModel;

using System.Text;

using System.ServiceModel.Activation;

using Tycon.BIZUIT.Security;

using System.ServiceModel.Channels;

using System.Security.Cryptography.X509Certificates;

using System.ServiceModel.Description;

using System.ServiceModel.Security;

namespace MyCompany

{

public class Calculator : IDerivativesCalculator

{

#region IDerivativesCalculator Members

decimal IDerivativesCalculator.CalculateDerivative(int days, string[] symbols, string[] functions)

{

return (decimal)(System.DateTime.Now.Millisecond);

}

#endregion

}

public class MyServiceHostFactory : ServiceHostFactory

{

public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)

{

return new MyServiceHost(baseAddresses);

}

}

class MyServiceHost : ServiceHost

{

public MyServiceHost(params Uri[] addresses)

: base(typeof(Calculator), addresses)

{

//base.ApplyConfiguration();

}

override protected void InitializeRuntime()

{

Binding SessionBinding = BindingHelper.CreateSessionBinding();

this.AddServiceEndpoint(typeof(IDerivativesCalculator), SessionBinding, "custom", new Uri("http://localhost/DerivativesCalculator/Service.svc"));

base.InitializeRuntime();

}

}

}

Now, the web.config:

Code Snippet

< xml version="1.0" >

<configuration>

<connectionStrings>

<add name="SqlConn" connectionString="Password=sa;Persist Security Info=True;User ID=sa;Initial Catalog=usersdatabase;Data Source=.\sqlexpress" providerName="System.Data.SqlClient" />

</< FONT>connectionStrings>

<system.serviceModel>

<services>

<service

name="MyCompany.Calculator"

behaviorConfiguration="CalculatorServiceBehavior">

<endpoint address="username"

binding="wsHttpBinding"

bindingConfiguration="Binding1"

contract="MyCompany.IDerivativesCalculator"/>

</< FONT>service>

</< FONT>services>

<bindings>

<wsHttpBinding>

<binding name="Binding1">

<security mode ="Message">

<message clientCredentialType ="UserName"/>

</< FONT>security>

</< FONT>binding>

</< FONT>wsHttpBinding>

</< FONT>bindings>

<behaviors>

<serviceBehaviors>

<behavior name="CalculatorServiceBehavior">

<serviceAuthorization principalPermissionMode ="UseAspNetRoles" roleProviderName ="SqlRoleProvider" />

<serviceCredentials>

<userNameAuthentication userNamePasswordValidationMode ="MembershipProvider" membershipProviderName ="SqlMembershipProvider"/>

<serviceCertificate storeLocation ="LocalMachine"

storeName ="My"

x509FindType ="FindBySubjectName"

findValue ="localhost" />

</< FONT>serviceCredentials>

<serviceDebug includeExceptionDetailInFaults="true" />

<serviceMetadata httpGetEnabled="true"/>

</< FONT>behavior>

</< FONT>serviceBehaviors>

</< FONT>behaviors>

</< FONT>system.serviceModel>

<appSettings/>

<system.web>

<compilation debug="false"/>

<authentication mode="Windows"/>

<membership defaultProvider="SqlMembershipProvider" userIsOnlineTimeWindow="15">

<providers>

<clear />

<add

name="SqlMembershipProvider"

type="System.Web.Security.SqlMembershipProvider"

connectionStringName="SqlConn"

applicationName="MembershipAndRoleProviderSample"

enablePasswordRetrieval="false"

enablePasswordReset="false"

requiresQuestionAndAnswer="false"

requiresUniqueEmail="true"

passwordFormat="Hashed" />

</< FONT>providers>

</< FONT>membership>

<roleManager enabled ="true"

defaultProvider ="SqlRoleProvider" >

<providers>

<add name ="SqlRoleProvider"

type="System.Web.Security.SqlRoleProvider"

connectionStringName="SqlConn"

applicationName="MembershipAndRoleProviderSample"/>

</< FONT>providers>

</< FONT>roleManager>

</< FONT>system.web>

</< FONT>configuration>

And I get this error:

Code Snippet

Server Error in '/DerivativesCalculator' Application.


Re: Authenticate several security tokens with the same service

Matt_

Maybe someone can point me on the direction of implementing a genericXmlToken, since it is a "primitive" token, maybe I don't have to create a custombinding there, and then configure all the endpoints from the web.config, and with the advantage of being able to create the client proxy...

Thanks, Matias





Re: Authenticate several security tokens with the same service

Brent Schmaltz MSFT

http://www.bizuit.com/security/tokens/sessioninfo

Is this your own token type Have you overloaded a handler by extending SecurityTokenManager





Re: Authenticate several security tokens with the same service

Matt_

Yes, I did. Actually, if I configure my customToken only, it works fine, but when I configure two endpoints, one with a custombinding and another with wsHttpBinding, it doesn't...

Thanks, Matias