2

I have an internal-facing RESTful web service. There are various client applications using the service, and the client apps themselves have end users. The web service needs to authorize requests based on the end user identities.

The question: What are the typical options for authenticating the end user here? That is, I want to authenticate the user, not the client application. (I don't mind if authenticating the client application is part of the scheme, but ultimately I need to know that the end user is who I think he or she is.)

One possible scheme, for example, would be to have per-client system accounts, and then have the client simply assert the user's identity (e.g. in an HTTP request header, say). So we authenticate the client application and delegate user authentication to the client. I don't think this is a very strong scheme, though, because it depends too much on keeping the system account credentials secret. I have seen too many examples of people e-mailing system account credentials around to put much faith in this sort of approach.

Another approach might be to have the client app, upon user login, use the user's credentials to get a token from the API, and then use that token for subsequent API requests. That way the authentication is user-specific without requiring the client app to hang onto the username/password credentials.

Anyway I'd like to have a better sense for the range of options I should be considering here.

1 Answer 1

2

The problem that you describe with "delegated authentication" is a real one. It means that a "client application" using it's credentials has access to the whole breadth of user data. This access can be used maliciously (for example a "semi-trusted" app harvesting api data) or negligently (for example an app accidentally exposing a Direct Object Reference Vulnerability - https://www.owasp.org/index.php/Top_10_2010-A4-Insecure_Direct_Object_References)

Probably the most prevalent "token based" scheme is OAuth2 (http://oauth.net/2/), and the precursor, OAuth, which many sites choose to continue to use.

OAuth2 has a number of roles:

  1. resource owner (the user in your case)
  2. resource server (your api)
  3. client (the apps you talk about)
  4. authorization server (not clear who or what would fulfil this role in your case)

The basic scheme is that the resource owner authenticates using their credentials directly with the authorization server. They are then asked if they want to grant some information (which may just be a persistent identifier, or a description of the information exposed by your api) to some client. When they accept an 'auth code' is sent to the client and they use that (combined with their own credentials) to receive an 'access token'. This access token can then be used to authenticate against the resource server (which can check it's authenticity back against the authorization server).

Normally the way this is used is that the authorization server and the resource server are owned and managed by the same entity (for example google and facebook would fulfil this role) and then clients are independently managed.

The scheme can also be used internally within an organisation without the "explicit grant" which can still at least confirm that a specific end-user is present before releasing any data from an api.

Sign up to request clarification or add additional context in comments.

5 Comments

This is really helpful. I considered OAuth2 but assumed that it was a poor match because I have fine-grained ACLs on the service side, and all the OAuth2 examples I've seen involve granting coarse-grained permissions (e.g., give such-and-such app permission to post on your wall).
So the magic search term for you is 'scopes'. OAuth2 has an extensible scopes mechanism which means you can add pretty fine grained controls but it relies on you agreeing it in advance with the Authorization Server. In this case the 'grant' screen would ask if they were willing to give access to e.g. "your mother's shoe size" based on a scope of 'mothersshoesize'. The scopes that an app wants are passed to the Authorization Server when the client redirects the user.
Can I just have the client pass the token to the web service, and then have the web service resolve the token to a user and then apply any ACLs? I'm not really looking to give the end user the ability to grant the client app to access such-and-such data (which I think is the normal OAuth use case). Instead, the client authenticates to the service as the end user (e.g., by passing the token), and so the client can do whatever service allows that end user to do. Let me know if OAuth2 is still a candidate here.
Absolutely. If you know the full set of users in advance then you can just apply a standard "whitelist" of users for certain features. This is really using OAuth2 for just plain old authentication (and you would be applying custom authorization in your service).
Alright Phil, thanks a lot sir. You've given me a good direction.