Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OAuth 2.0 integrated with REST WCF Service application

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

like image 742
Reha Avatar asked Feb 28 '13 14:02

Reha


People also ask

How does OAuth2 work for rest?

OAuth2 allows authorization without the external application getting the user's email address or password. Instead, the external application gets a token that authorizes access to the user's account. The user can revoke the token for one application without affecting access by any other application.

How does OAuth work in REST API C#?

OAuth is a token based authorization mechanism for REST Web API. You develop the authorization with the API only once up until the expiration time of the token. The generated token is then used each time the REST Web API is called, saving an authorization step every time the REST Web API is called.

What is OAuth 2.0 and how it works?

OAuth 2.0, which stands for “Open Authorization”, is a standard designed to allow a website or application to access resources hosted by other web apps on behalf of a user. It replaced OAuth 1.0 in 2012 and is now the de facto industry standard for online authorization.


1 Answers

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.

like image 166
Iain Avatar answered Oct 20 '22 20:10

Iain