Gert Hermans
Gert Hermans

Reputation: 829

Communication between asp.net MVC application and WCF services with windows based security

I'm making an asp.net MVC application that communicates with wcf services on IIS. The asp.net MVC application works with a normal login mechanism (username, password). In the wcf services I want to log in (with this password and username) to get the windowsidentity of the user.(the security on the wcf services are windows based)

The issue is how can I communicate from the asp.net MVC application with the services in this way and keep the asp.net MVC application as stateless as possible (putting a password in the session state is definately not allowed)

Ideas about how to get this done are very much appreciated.

This drawing might make things clearer: Architecture Mobile App Website

Upvotes: 0

Views: 2465

Answers (3)

Gert Hermans
Gert Hermans

Reputation: 829

After a lot of experimentating I've found a way to do this. I'll refer to the ASP.NET MVC application as the client.

Through a loginService , the client can pass the username and password. In this service this data is used to check if there is a corresponding windows account. If so a guid is created and this guid along with the username and password (both encrypted) will be stored in a database. The service returns the guid to the client which puts this guid in the session state.

When another call is made to a wcf service, the client sends this guid in a messageheader called 'id' . In wcf I use a ServiceAuthorizationManager to check the incoming messages. If there is a messageheader called 'id', this id will be used to get the corresponding username and password in the database, and with this username and password get the windowsidentity and then impersonate it.(this all happens before it reaches the service itself)

When the user gets to the service, he will be impersonated with his windows account.

Upvotes: 0

Shetty
Shetty

Reputation: 1892

If I have understood your question correctly,you need a way to provide windows authentication to your WCF service. Following link can help.

Link

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1038730

Here's an article explaining step by step how to authenticate using an username/password in a WCF service:

http://blog.adnanmasood.com/2010/04/29/step-by-step-guide-for-authenticating-wcf-service-with-username-and-password-over-ssl/

It uses a custom UserNamePasswordValidator on the service side:

public class CustomValidator : UserNamePasswordValidator
{
    public override void Validate(string userName, string password)
    {
        if (userName == "test" && password == "secret")
        {
            return;
        }
        throw new SecurityTokenException("Unknown Username or Password");
    }
}

which could be configured as a service behavior:

<system.serviceModel>
    <services>
        <service behaviorConfiguration="WcfService.Service1Behavior" name="MySamples.WcfService">
            <endpoint address="" binding="wsHttpBinding" contract="MySamples.IWcfService" bindingConfiguration="SafeServiceConf">
                <identity>
                    <dns value="localhost"/>
                </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="WcfService.Service1Behavior">
                <serviceMetadata httpGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceCredentials>
                    <userNameAuthentication
                        userNamePasswordValidationMode="Custom"
                        customUserNamePasswordValidatorType="MySamples.CustomValidator, WcfService" 
                    />
                </serviceCredentials>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <bindings>
        <wsHttpBinding>
            <binding name="SafeServiceConf" maxReceivedMessageSize="65536">
                <readerQuotas maxStringContentLength="65536" maxArrayLength="65536" maxBytesPerRead="65536" />
                <security mode="TransportWithMessageCredential">
                    <message clientCredentialType="UserName" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
</system.serviceModel>

and on the client:

using (var client = new WcfServiceClient())
{
    client.ClientCredentials.UserName.UserName = "test";
    client.ClientCredentials.UserName.Password = "secret";
    var result = client.SomeMethod();
}

Upvotes: 1

Related Questions