OAuth 2.0 integrated with REST WCF Service application

Reha picture Reha · Feb 28, 2013 · Viewed 8.6k times · Source

I need help with integrating an Authentication layer OAuth2.0 with a REST Service using VS 2012 WCF Service application template in C#. This WCF needs to issue tokens for the authorization and authentication of the service before allowing the Client(Consumer) to access any of its resources. Three legged authentication is what I am looking at. Much like the Twitter, LinkedIn, Google OAuth implementation.

Have searched the internet extensively for an REST WCF API integrated with OAuth and have not come across any suitable leads that is helping me. I have looked at an old example http://weblogs.asp.net/cibrax/archive/2008/11/14/using-the-wcf-oauth-channel-with-an-ado-net-service.aspx

I have used this example to integrate with an existing Rest WCF. When I run the service, I am getting the "500 Internal server error" and other times the operation just times out.

Here is the implementation that is causing issues.

I had to add the interceptor as below and referenced in the .svc Factory="DemoRESTOAuthService.AppServiceHostFactory":

class AppServiceHostFactory : System.ServiceModel.Activation.ServiceHostFactory
{
     //<summary>
     //Factory method called by WCF to create a <see cref="ServiceHost"/>.
     //</summary>
     //<param name="serviceType">The type of the service to be created.</param>
     //<param name="baseAddresses">Collection of base addresses where the <see cref="ServiceHost"/> can listen.</param>
     //<returns>An instance of <see cref="ServiceHost"/>.</returns>
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        try
        {
            Microsoft.ServiceModel.Web.WebServiceHost2 result = new Microsoft.ServiceModel.Web.WebServiceHost2(serviceType, true, baseAddresses);

            result.Interceptors.Add(new OAuthChannel.OAuthInterceptor(DemoRESTOAuthService.OAuth.OAuthServicesLocator.Provider, DemoRESTOAuthService.OAuth.OAuthServicesLocator.AccessTokenRepository));

            return result;
        }
        catch(Exception e)
        {
           throw e;
        }
    }
}

When I debug using a log file, I just am able to tell that an exception is thrown, in the OAuthInterceptor.cs of OAuthChannel assembly. I have used tracelog and fiddler, but I am not getting much help understanding the error, other than 500 internal server error.

public override void ProcessRequest(ref RequestContext requestContext)
    {
        if (requestContext == null || requestContext.RequestMessage == null)
        {
            return;
        }

        Message request = requestContext.RequestMessage;


        HttpRequestMessageProperty requestProperty = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];


        OAuthContext context = new OAuthContextBuilder().FromUri(requestProperty.Method, request.Headers.To);


        try
        {
            _provider.AccessProtectedResourceRequest(context);


            OAuthChannel.Models.AccessToken accessToken = _repository.GetToken(context.Token);


            TokenPrincipal principal = new TokenPrincipal(
                new GenericIdentity(accessToken.UserName, "OAuth"),
                accessToken.Roles,
                accessToken);

            InitializeSecurityContext(request, principal);
        }
        catch (OAuthException authEx)
        {
            XElement response = XElement.Load(new StringReader("<?xml version=\"1.0\" encoding=\"utf-8\"?><html xmlns=\"http://www.w3.org/1999/xhtml\" version=\"-//W3C//DTD XHTML 2.0//EN\" xml:lang=\"en\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.w3.org/1999/xhtml http://www.w3.org/MarkUp/SCHEMA/xhtml2.xsd\"><HEAD><TITLE>Request Error</TITLE></HEAD><BODY><DIV id=\"content\"><P class=\"heading1\"><B>" + HttpUtility.HtmlEncode(authEx.Report.ToString()) + "</B></P></DIV></BODY></html>"));
            Message reply = Message.CreateMessage(MessageVersion.None, null, response);
            HttpResponseMessageProperty responseProperty = new HttpResponseMessageProperty() { StatusCode = HttpStatusCode.Forbidden, StatusDescription = authEx.Report.ToString() };
            responseProperty.Headers[HttpResponseHeader.ContentType] = "text/html";
            reply.Properties[HttpResponseMessageProperty.Name] = responseProperty;
            requestContext.Reply(reply);

            requestContext = null;
        }
    }

Can anyone out there please help me with an insight as to what is going on?

Or can you please help me with any other suitable examples, pointers, tips or documentations for three legged OAuth Provider implementation. I am literally stuck with this issue for past one week. Any help is appreciated.

Thanks in advance

Answer

Iain picture Iain · Nov 10, 2013

Why don't you use a framework such as ServiceStack which has OAuth2 authentication providers already built: https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization

Or if you don't want to use the entire stack, look at their code to see how it differs from your own.