Truckarn
Truckarn

Reputation: 113

Adding simple security to SOAP WCF hosted on Azure webapp

I have hosted a SOAP WCF on an azure web application. This service is going to be consumed by servers only and contains no UI. I only need one service account to auth my WCF. I cannot use oauth since it's SOAP. I have read up a little on ACS, but it seems overkill in my case since I just want to use one account to secure my WCF. My thinking was I was going to leverage the Azure AD to make a service account there and use it to secure the service.

Is this even possible on a web app or do i need to host it on a web role? In any case how do i accomplish simple security on my WCF based on my premises?

Upvotes: 4

Views: 2127

Answers (2)

Emmanuel DURIN
Emmanuel DURIN

Reputation: 4913

Detailed answer example

After general discussion, here is a detailed example for establishing transport security + simple password (in IIS, on premises or Azure I just tested it)

This is very simple.
- No role, no declarative or programmatic control based on identity.
- Identity is hard coded.
- No usage of message security that is stronger (man in the middle).
- Transport security is the minimum because Basic authentication is not securized.

That security scenario is short to implement

1. Creation of a Web Service with transport security

 <system.serviceModel>
 <bindings>
  <basicHttpBinding>
    <binding name="BasicBindingConfiguration">
      <security mode="Transport">
        <transport clientCredentialType="None"/>
      </security>
    </binding>
  </basicHttpBinding>
 </bindings>
<services>
  <service name="HelloServiceLibrary.HelloService" behaviorConfiguration="customIdentificationBehavior">
    <endpoint address=""
              binding="basicHttpBinding"
              contract ="HelloServiceLibrary.IHelloService"
              name="basicEndpoint"
              bindingConfiguration="BasicBindingConfiguration">
    </endpoint>

2. Declaration of a module to find Basic-Auth

<system.webServer>
  <modules>
    <add name="BasicAuthenticationModule"
         type="Security.UserNameModuleAuthenticator,App_Code/Security" />
  </modules>
</system.webServer>  

3. Implementation of the module :

public class UserNameModuleAuthenticator : IHttpModule{
    ...
    public void OnAuthenticateRequest(object source, EventArgs eventArgs){
      HttpApplication app = (HttpApplication)source;
      string authStr = app.Request.Headers["Authorization"];
      string username = ...; // from header 
      string password = ...; // from header 
      if (username == "gooduser" && password == "password")
            {
                app.Context.User = new GenericPrincipal(new GenericIdentity(username, "Custom Provider"), null);
            }
            else
            {
                DenyAccess(app);
                return;
            }

4 Configure Client for passing basic authentication

<system.serviceModel>
  <bindings>
    <basicHttpBinding>
      <binding name="basicEndpoint">
        <security mode="Transport" >
          <transport clientCredentialType="Basic"
                     proxyCredentialType="None"
                     realm="" />
        </security>
      </binding>
    </basicHttpBinding>
  </bindings>
  <client>
    <endpoint address="https://localhost/TransportUsernameService/HelloService.svc"
      binding="basicHttpBinding" bindingConfiguration="basicEndpoint"
      contract="SecureServiceReference.IHelloService" name="basicEndpoint" />
  </client>
</system.serviceModel>

5. On client pass **credentials to the server**

HelloServiceClient client = new HelloServiceClient("basicEndpoint",
    new EndpointAddress("https://testsecurewebservice.azurewebsites.net/HelloService.svc"));

client.ClientCredentials.UserName.UserName = userName;
client.ClientCredentials.UserName.Password = password;
String msg = client.SayHello(userName);

Possible Extensions

  • Create/manage some users (using ASP.Net Provider or custom base)
  • Have some roles
  • Put some declarative permissions on methods like :
[PrincipalPermission(SecurityAction.Demand, Role = "Manager")]

Complete solution here : http://1drv.ms/1Q5j9w0

Regards

Upvotes: 6

Emmanuel DURIN
Emmanuel DURIN

Reputation: 4913

For authentication, you could use :

  • Username authentication for passing {login,password}.
  • X509 mechanism for identifying the client (requires to deploy ceritificates on clients)
  • Custom authentification

For Transfer security, you could use :

  • Message security using a certificate installed on the server side
  • Transport security (HTTPS)

But it's strongly recommended that you also use some message security more than transport security. Transport (Https/SSL) can be attacked with man in the middle (taking control of a router).

The drawback of message security is that you ve got to install a certificate on the server :

It is much easier to setup a certificate in a web role where you can setup in the Role.OnStart method

  • If you are keen on a web app, here is a link for providing transport security with username
    (you should skip the part with ASP.NET MemberShip/Role provider because you want a single user and a database is extra work) :

https://msdn.microsoft.com/en-us/library/ff649647.aspx

  • If you are keen on message security, you should go to web roles and use a certificate for message security.

Link for custom authentication with message security :
http://www.codeproject.com/Articles/33872/Custom-Authorization-in-WCF

Regards

Upvotes: 1

Related Questions