Using OAuth2 with SOAP


I started at Microsoft when SOAP was all the rage, before there was such a thing as WCF. So it is with some nostalgia that I tried to combine one of latest technologies: Universal App Platform (UAP) with SOAP using OAuth2 protocol for authentication. One possible application of this approach would be for folks who are slowly migrating from WCF to REST and/or needing to mix REST and SOAP services in their current applications. Although the sample uses a UWP client, same code would apply to other .NET clients, e.g. WPF needing to use OAuth2 for authenticating to a SOAP service.

The basics of the attached samples are as follows:

  1. It is using Azure AD to provide the authentication service and therefore an OAuth2 access token to a UAP client.
  2. The client is using the ADAL library to acquire the token (see https://github.com/Azure-Samples/active-directory-dotnet-windows-store for more details).
  3. The SOAP service is a web hosted WCF service.
There are two main choices for passing authentication data to a SOAP service: via a custom SOAP header or, if the service is using http (as in my case) via an http header, e.g. the Authorization header. The first approach is more generic in that it could support non-http WCF services. The 2nd is likely faster (no xml parsing). Since UWP only supports basicHttpBinding, unless the service also supports other, non UWP clients, using non-http bindings, the http header approach is just as good. The attached sample uses the custom header approach but includes commented code for the http-header approach as well.
To call the SOAP service, after regular service proxy was added to the UWP client and an OAuth2 token was obtained, the client does the following to create and include a custom SOAP header with the OAuth2 access token:
 var svc = new ServiceReference1.Service1Client();
using (var scope = new OperationContextScope(svc.InnerChannel))
{
var authHeader = MessageHeader.CreateHeader("Token", "http://tempuri.org", result.AccessToken);
OperationContext.Current.OutgoingMessageHeaders.Add(authHeader);
// Do this if you want to use http header instead
//var httpRequestProperty = new HttpRequestMessageProperty();
//httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] = result.AccessToken;
//OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
var res = await svc.GetDataAsync(inp);
_result.Text = res.ToString();
}
The service, which unfortunately cannot use the OWIN stack to validate the JWT token, implements its own ServiceAuthorizationManager-derived class and a JWT-validator. The validator (called AADJWTValidator in the sample) relies on the Azure AD federation metadata endpoint to retrieve the signing key.
That simple!

SOAPWithUWP.zip

Comments (2)

  1. Bjørn says:

    The _nextSync offset should add one hour, not subtract.

Skip to main content