Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OAuth and WCF SOAP service

I'm trying to implement OAuth security for a WCF SOAP service. I could find samples online which talks about OAUTH and REST service. Is there any best approach to use OAuth with WCF SOAP service. If it is possible to secure WCF SOAP usig OAUth, I also would like to know whether I could use claims based authorization in this case.

like image 691
Sherin Mathew Avatar asked Mar 04 '15 04:03

Sherin Mathew


People also ask

Does OAuth work with SOAP?

To perform the OAuth authentication, you need to pass the OAuth access token along with the request. In SOAP web services, the OAuth access token can be passed in a SOAP Header inside the SOAP envelope or in the Authorization HTTP header of a request.

What is the difference between WCF and SOAP?

Using service behavior classes, WCF supports multi-threading, but web services don't. 9. In ASP.NET Development services, SOAP messages are exchanged over HTTP, but WCF services can exchange the message using any format over any transport protocol. Though, SOAP is a default format that WCF uses.

Is WCF restful or SOAP?

Normally, a WCF service will use SOAP, but if you build a REST service, clients will be accessing your service with a different architectural style (calls, serialization like JSON, etc.).

Can OAuth be used for REST API?

OAuth is an authorization framework that enables an application or service to obtain limited access to a protected HTTP resource. To use REST APIs with OAuth in Oracle Integration, you need to register your Oracle Integration instance as a trusted application in Oracle Identity Cloud Service.


1 Answers

The short answer is a simple yes, you can do this. I tried to find an "official" way to do this and I was not successful, mostly because OAuth is not really designed for this scenario, more on that later. First though how to actually do it. One way to do it would be to provide a custom ServiceAuthorizationManager and inside of it do something like this

public class OAuthAuthorizationManager : ServiceAuthorizationManager
{
    protected override bool CheckAccessCore(OperationContext operationContext)
    {
        // Extract the action URI from the OperationContext. Match this against the claims 
        // in the AuthorizationContext. 
        string action = operationContext.RequestContext.RequestMessage.Headers.Action;

        try
        {
            //get the message
            var message = operationContext.RequestContext.RequestMessage;

            //get the http headers
            var httpHeaders = ((System.ServiceModel.Channels.HttpRequestMessageProperty)message.Properties.Values.ElementAt(message.Properties.Keys.ToList().IndexOf("httpRequest"))).Headers;


            //get authorization header
            var authHeader = httpHeaders.GetValues("Authorization");

            if (authHeader != null)
            {
                var parts = authHeader[0].Split(' ');

                if (parts[0] == "Bearer")
                {
                    var tokenClaims = ValidateJwt(parts[1]);
                    foreach (System.Security.Claims.Claim c in tokenClaims.Where(c => c.Type == "http://www.contoso.com/claims/allowedoperation"))
                    {
                        var authorized = true;
                        //other claims authorization logic etc....
                        if(authorized)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;

        }
        catch (Exception)
        {
            throw;
        }

    }

    private static IEnumerable<System.Security.Claims.Claim> ValidateJwt(string jwt)
    {
        var handler = new JwtSecurityTokenHandler();
        var validationParameters = new TokenValidationParameters()
        {
            ValidAudience = "urn://your.audience",
            IssuerSigningKey = new InMemorySymmetricSecurityKey(Convert.FromBase64String("base64encoded symmetric key")),
            ValidIssuer = "urn://your.issuer",
            CertificateValidator = X509CertificateValidator.None,
            RequireExpirationTime = true
        };

        try
        {
            SecurityToken validatedToken;
            var principal = handler.ValidateToken(jwt, validationParameters, out validatedToken);
            
            return  principal.Claims;

        }
        catch (Exception e)
        {
            return new List<System.Security.Claims.Claim>();
        }

    }
}

be sure to also set the web.config to use this custom class using the serviceAuthorizationElement

This example requires the System.IdentityModel.Tokens.Jwt nuget package as well, your tokens might be in another format though and in that case you would need to just replace that logic in the example. Also, note that this example is assuming you will be passing our token on the Authorization header in the http request, the OAuth 2.0 Authorization Framework: Bearer Token Usage documentation also specifies that both form encoded body parameters and URI query paramters may be used as well. The form encoded body parameter method is probably entirely incompatible with SOAP services but I see no reason you could not adapt this code to also look at the query parameter method if needed.

What this code does is for every single request to your service the CheckAccessCore method will fire, inside it attempts to extract and validate the JWT oauth token then you can use the extracted principle and associated claims to authorize or deny authorization to the request.

All of this said, I think the best approach would be to not use OAuth at all, the above works but it is a hack to how WCF SOAP services are meant to be secured. OAuth is also not meant to authenticate the user, so you will need to do that in some other way prior to passing the bearer token obtained from authentication on to your service. If you absolutely must use OAuth you can use the above to get you started, there may be better ways but it is not easy by any measure to make it work and be readable. If you have not looked into WS-Security you should do that and familiarize yourself with the abundance of information and possibilities that exist for securing a soap based service most of which have numerous examples to go on here.

like image 104
Mark Avatar answered Sep 30 '22 23:09

Mark