4

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?

Truckarn
  • 113
  • 1
  • 10
  • Yes it is pretty likely that it is possible because there are many security issues involved with WCF services. They can be hosted in Azure web sites (restriction on ports 80/443). By security what do you mean exactly : identification of client, cryting the messages, identifying the server ... ? – Emmanuel DURIN Nov 02 '15 at 12:14
  • 1
    I want to use some sort of wcf security so that the WCF is not totally exposed for anyone to use. Then if its wsfederation/bearer/trust or whatever does not matter. Basically I want to find out is which WS- security method i should use regarding my use case and against what should I authenticate and how its configured. – Truckarn Nov 02 '15 at 12:25
  • You can create a pretty simple ACS setup by using SWT with ACS as the Auth provider. Why do you feel ACS is overkill? – j-u-s-t-i-n Nov 02 '15 at 14:39
  • @Aleve, I just a detailed answer, I hope it will help. It also inclludes a full solution as a link. Tell me if it's too simple. But may be it should be another question if you want some roles and declarative permissions – Emmanuel DURIN Nov 04 '15 at 13:57

2 Answers2

6

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

Emmanuel DURIN
  • 4,803
  • 2
  • 28
  • 53
  • Thank you very much! Tried it with a soap on a azure webapp and it seems to be working! Could you please explain a little bit about the drawbacks regarding security using this kind of solution? – Truckarn Nov 05 '15 at 12:49
  • I explained it in the other message : "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)." – Emmanuel DURIN Nov 05 '15 at 12:59
  • If you fear man in the middle attack, the you should use wsHttpBinding with message security. There should be aX509 certificate used for encrypting. – Emmanuel DURIN Nov 05 '15 at 13:00
  • Thank you, i ended up stapling my entire webapp with a module. I used a variation of your provided example. – Truckarn Apr 07 '16 at 15:37
1

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

Emmanuel DURIN
  • 4,803
  • 2
  • 28
  • 53