Monday, 30 July 2012

Securing WCF Services exposed on Azure Service Bus Namespace - Part 6


Analyzing how Service Identities used for securing the service

If you refer the following post, we created service bus namespace and creating Relying Party Application for each endpoint. We also created two service identities thiru and raja under Adding New Service Identities section.
http://www.dotnettwitter.com/2012/06/securing-wcf-services-exposed-on.html

Note: These two identities are some names to understand and the names can be meaningful when replacing with a company/customer name.

When we modify Rule Groups for each Relying Party Application, we had configured thiru identity with Send claim (refer: Adding Rule Groups - Step 3) which given access right to send requests on Service Bus for a particular endpoint (using thiru identity). It also configured raja identity with Listen claim (refer: Adding Rule Groups - Step 4) which can listen on the Service Bus for the same endpoint. It is also to note, the Rule Groups for each Relying Party application is not referring any another Rule Groups (such as Rule Group referred for base endpoint) and has its own and only one Rule Group defined.

For more information, below is the configuration setup.

Relying Party Application 1:
Name: Service Bus
Endpoint: http://dntsales.servicebus.windows.net/
Rule Group: Default Rule Group for ServiceBus (Configured with its own Rule Groups)
Output Claims: owner with Send claim, owner with Listen claim, owner with Manage claim

Relying Party Application 2:
Name: Service Bus Authentication with Service Identity for Http Endpoint
Endpoint: http://dntsales.servicebus.windows.net/Http/Order/Test/V0101/
Rule Group: Default Rule Group for Service Bus Authentication with Service Identity for Http Endpoint (Configured with its own Rule Group and not referred other Rule Groups)
Output Claims: thiru with Send claim, raja with Listen claim

Relying Party Application 3:
Name: Service Bus Authentication with Service Identity for Tcp Endpoint
Endpoint: http://dntsales.servicebus.windows.net/Tcp/Order/Test/V0101/
Rule Group: Default Rule Group for Service Bus Authentication with Service Identity for Tcp Endpoint (Configured with its own Rule Group and not referred other Rule Groups)
Output Claims: thiru with Send claim, raja with Listen claim

Consider - if we are accessing endpoint http://dntsales.servicebus.windows.net/Http/Order/Test/V0101/ from client application, which can be possible only by thiru or raja service identities and even the owner identity also not possible to expose/consume for that endpoint (as the Rule Group not refers that identity).

Once the identity is authenticated, the Service Bus will authorize the claim. In this case, thiru identity has rights only to send the request to Service Bus endpoint and raja identity can only able to listen the request which comes to Service Bus endpoint. So, the consumer application can use thiru identity for consuming the service and the service application can use raja identity for exposing the service.

Note: If we use owner identity either in service application or client application it never works (for the endpoints defined).

Let us verify the client application by changing the service identity and keys -

Attempt 1
Change the configuration as below –
<appSettings>
 <add key="ServiceNamespace" value="dntsales" />
 <add key="IssuerName" value="thiru" />
 <add key="IssuerSecret" value="fBnxJPexOod7V96awTbnS2wjiMJV1Mo0J0xzr/tBr44=" />
 <add key="CustomerServiceEndPointNameTcp" value="Tcp/Order/Test/V0101" />
 <add key="CustomerServiceEndPointNameHttp" value="Http/Order/Test/V0101" />
 <add key="ServiceConsumingProtocol" value="Tcp"/>
</appSettings>
As per the configuration, I am calling the TCP endpoint sb://dntsales.servicebus.windows.net/Tcp/Order/Test/V0101/ using the service identity thiru and its the symmetric key.

Following is the output of the configuration.

Attempt 2
Change the configuration as below –
<appSettings>
 <add key="ServiceNamespace" value="dntsales" />
 <add key="IssuerName" value="raja" />
 <add key="IssuerSecret" value="K5GIOAyluK5W4E2+As+AnMIOPV1mKWoNw9ggNAmGSR4=" />
 <add key="CustomerServiceEndPointNameTcp" value="Tcp/Order/Test/V0101" />
 <add key="CustomerServiceEndPointNameHttp" value="Http/Order/Test/V0101" />
 <add key="ServiceConsumingProtocol" value="Tcp"/>
</appSettings>
In this attempt, I am calling the same TCP endpoint sb://dntsales.servicebus.windows.net/Tcp/Order/Test/V0101/ using the service identity raja and its the symmetric key. As per the AC settings, service identity raja has no claim on Listen. So it suppose to throw some error.

Following is the output of the configuration.
The screen clearly shows the authorization issue as we use wrong identity.

Attempt 3
Change the configuration as below –
<appSettings>
 <add key="ServiceNamespace" value="dntsales" />
 <add key="IssuerName" value="owner" />
 <add key="IssuerSecret" value="cFkjM3qwMHrSFr1qrMr4ErfGIUGoT/OwmEi9FMyT8k4=" />
 <add key="CustomerServiceEndPointNameTcp" value="Tcp/Order/Test/V0101" />
 <add key="CustomerServiceEndPointNameHttp" value="Http/Order/Test/V0101" />
 <add key="ServiceConsumingProtocol" value="Tcp"/>
</appSettings>
In this attempt, I am calling the same endpoint using the service identity owner and its the symmetric key. As per the AC settings, service identity owner has no claim on either Send, Listen or Manage. So it suppose to throw some error.

Following is the output of the configuration.

Please look at the points rounded rectangle that shows the error clearly 'No output claims were generated during the rule processing', as we dont use owner for either of the claims.

Attempt 4
Let us modify the Relying Party Application in the ACS portal which adds one more rule created for base hierarchy and verify the output. So open the ACS portal (select the namespace, click the Access Control Service icon on the top – which take you to ACS portal).

Select the Relying Party Application from left hand menu and open the Service Bus Authentication with Service Identity for Tcp Endpoint Relying Party Application.
Scroll down to Authentication Settings section and select the Default Rule Group for ServiceBus rule group. Save the details.
Now the Relying Party Application will also look for the input claim owner and create output claim if present.

If we run the client application with the same configuration done in previous attempt (Attempt 3), the application will get success in authentication and authorization and show the screen.

Attempt 5
Change the configuration as below –
<appSettings>
 <add key="ServiceNamespace" value="dntsales" />
 <add key="IssuerName" value="raja" />
 <add key="IssuerSecret" value="K5GIOAyluK5W4E2+As+AnMIOPV1mKWoNw9ggNAmGSR4=" />
 <add key="CustomerServiceEndPointNameTcp" value="Tcp/Order/Test/V0101" />
 <add key="CustomerServiceEndPointNameHttp" value="Http/Order/Test/V0101" />
 <add key="ServiceConsumingProtocol" value="Http"/>
</appSettings>
In this attempt, I am calling the Http endpoint using the service identity raja and its the symmetric key. As per the AC settings, service identity raja has no claim to Send the request. So it suppose get an authorization error.

Following is the output of the configuration.
The error is more clear then the TCP endpoint error.

Attempt 6
From this attempt let us look at the service application. As of now, the transportClientEndpointBehavior configuration section looks as below
<behaviors>
  <endpointBehaviors>
  <behavior name="sharedSecretClientCredentials">
    <transportClientEndpointBehavior credentialType="SharedSecret">
      <clientCredentials>
        <sharedSecret issuerName="raja" issuerSecret="K5GIOAyluK5W4E2+As+AnMIOPV1mKWoNw9ggNAmGSR4=" />
      </clientCredentials>
    </transportClientEndpointBehavior>
    <ServiceRegistrySettings discoveryMode="Public" />
  </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="MyServiceTypeBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>
In this configuration, line #6 shows the service identity credentials on which the service is exposed to public on Service Bus. As per the configuration, the identity configured is raja which has Listen claim on both the endpoints (means, the identity can listen the request coming on the Service Bus endpoint).

When we run the service application, we will get the following output –

Attempt 7
We will change the service identity to thiru in the service application configuration file and look at the output.
Note: Restart the IIS server if the Auto-Start feature enabled for this service.
<transportClientEndpointBehavior credentialType="SharedSecret">
  <clientCredentials>
    <sharedSecret issuerName="thiru" issuerSecret="fBnxJPexOod7V96awTbnS2wjiMJV1Mo0J0xzr/tBr44=" />
  </clientCredentials>
</transportClientEndpointBehavior>
The output of the configuration would be -
The error clearly shows, the authorization failed on exposing the service because of we are using thiru which has Send claim and not Listen.

Final Understanding
So we can understand from this exercise, we have an option to authenticate and authorize the service using ACS service identities when we don’t have option of consuming any public identity providers such as Google Id, Yahoo Id, Live Id etc., or using ADFS.

This is a very simple example of securing the service exposed on Service Bus using ACS. ACS also provides lots more features then this.


0 Responses to “Securing WCF Services exposed on Azure Service Bus Namespace - Part 6”

Post a Comment