Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I authorize access to ServiceStack resources using OAuth2 access tokens via DotNetOpenAuth?
    text
    copied!<p>I've created an OAuth2 authorization server using DotNetOpenAuth, which is working fine - I'm using the resource owner password flow, and successfully exchanging user credentials for an access token.</p> <p>I now want to use that access token to retrieve data from secure endpoints in a ServiceStack API, and I can't work out how to do so. I've examined the Facebook, Google, etc. providers included with ServiceStack but it's not clear whether I should be following the same pattern or not.</p> <p>What I'm trying to achieve (I think!) is</p> <ol> <li>OAuth <strong>client</strong> (my app) asks <strong>resource owner</strong> ('Catherine Smith') for credentials</li> <li><strong>Client</strong> submits request to <strong>authorization server</strong>, receives an <strong>access token</strong></li> <li><strong>Client</strong> requests a secure <strong>resource</strong> from the <strong>resource server</strong> (<code>GET /users/csmith/photos</code>) <ul> <li>The <strong>access token</strong> is included in an HTTP header, e.g. <code>Authorization: Bearer 1234abcd...</code></li> </ul></li> <li>The <strong>resource server</strong> decrypts the <strong>access token</strong> to verify the identity of the <strong>resource owner</strong></li> <li>The <strong>resource server</strong> checks that the <strong>resource owner</strong> has access to the requested <strong>resource</strong></li> <li>The <strong>resource server</strong> returns the <strong>resource</strong> to the <strong>client</strong></li> </ol> <p>Steps 1 and 2 are working, but I can't work out how to integrate the DotNetOpenAuth resource server code with the ServiceStack authorization framework.</p> <p>Is there an example somewhere of how I would achieve this? I've found a similar StackOverflow post at <a href="https://stackoverflow.com/questions/10251508/how-to-build-secured-api-using-servicestack-as-resource-server-with-oauth2-0">How to build secured api using ServiceStack as resource server with OAuth2.0?</a> but it isn't a complete solution and doesn't seem to use the ServiceStack authorization provider model.</p> <p><strong>EDIT:</strong> A little more detail. There's two different web apps in play here. One is the authentication/authorisation server - this doesn't host any customer data (i.e. no data API), but exposes the /oauth/token method that will accept a username/password and return an OAuth2 access token and refresh token, and also provides token-refresh capability. This is built on ASP.NET MVC because it's almost identical to the AuthorizationServer sample included with DotNetOpenAuth. This might be replaced later, but for now it's ASP.NET MVC.</p> <p>For the actual data API, I'm using ServiceStack because I find it much better than WebAPI or MVC for exposing ReSTful data services. </p> <p>So in the following example:</p> <p><img src="https://i.stack.imgur.com/6611V.png" alt="sequence diagram"></p> <p>the <strong>Client</strong> is a desktop application running on a user's local machine, the <strong>Auth server</strong> is ASP.NET MVC + DotNetOpenAuth, and the <strong>Resource server</strong> is ServiceStack</p> <p>The particular snippet of DotNetOpenAuth code that's required is:</p> <pre><code>// scopes is the specific OAuth2 scope associated with the current API call. var scopes = new string[] { "some_scope", "some_other_scope" } var analyzer = new StandardAccessTokenAnalyzer(authServerPublicKey, resourceServerPrivateKey); var resourceServer = new DotNetOpenAuth.OAuth2.ResourceServer(analyzer); var wrappedRequest = System.Web.HttpRequestWrapper(HttpContext.Current.Request); var principal = resourceServer.GetPrincipal(wrappedRequest, scopes); if (principal != null) { // We've verified that the OAuth2 access token grants this principal // access to the requested scope. } </code></pre> <p>So, assuming I'm on the right track, what I need to do is to run that code somewhere in the ServiceStack request pipeline, to verify that the Authorization header in the API request represents a valid principal who has granted access to the requested scope.</p> <p>I'm starting to think the most logical place to implement this is in a custom attribute that I use to decorate my ServiceStack service implementations:</p> <pre><code>using ServiceStack.ServiceInterface; using SpotAuth.Common.ServiceModel; namespace SpotAuth.ResourceServer.Services { [RequireScope("hello")] public class HelloService : Service { public object Any(Hello request) { return new HelloResponse { Result = "Hello, " + request.Name }; } } } </code></pre> <p>This approach would also allow specifying the scope(s) required for each service method. However, that seems to run rather contrary to the 'pluggable' principle behind OAuth2, and to the extensibility hooks built in to ServiceStack's AuthProvider model.</p> <p><em>In other words - I'm worried I'm banging in a nail with a shoe because I can't find a hammer...</em></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload