Django Oauth Toolkit docs don't describe the redirect uris, authorization grant type, or client type fields when registering your application.
The tutorial says to set client type to confidential, grant type to password, and leave uris blank.
What do the other options do?
e.g. What is client type public vs confidential? What do the grant type password, credentials, authorization, implicit do? And what are the redirect uris for?
I have found sparse information about them but no actual explanations as they pertain to django rest framework and django oauth toolkit.
You'll get answer to all your questions once you read about Oauth2 Protocol from here
But I'll try to answer your questions in brief:
I'll be using the words client and Resource Server frequently. In Oauth2 protocol, client means the system which accesses resources, data or service. (It could be your mobile app or javascript app consuming REST API's of your API Backend (or Resource Server) . If you have implemented Facebook login in your mobile/JS apps, chances are, your API backend requests Facebook for user's information. In that case your API backend is being a client and Facebook is Resource Server)
Client Types:
Client type is either confidential or public depending on whether that client can keep it's client_secret a secret. (For example, an AngularJS app cannot keep it's client_secret hidden, since anyone can do "Inspect Element" in a browser and search for it, so such a client has to be registered as public.)
Authorization Grant Types:
There are four kinds of Authorization Grant Types in Oauth2 protocol.
Authorization Code:
In this grant type, the client requests for an authorization code first, then exchanges that authorization code for an access token. It's a two step procedure. Use this if the client is an outsider (more on it in Resource-owner password based).
Implicit:
Usually used along with public client_type. Instead of a two-step procedure above, the client gets access token in one go.
Resource-owner password based:
This is used when there is a high degree of trust between client and Resource Server. This is the case between your API backend and your Mobile app. (There is high degree of trust between your API backend and Javascript app too, but since it cannot keep it's client_secret a secret, you have to use Implicit Grant type with it). Facebook or Google etc. will never give you this kind of Authorization Grant because, for them, your API backend is an outsider.
Client Credentials:
It is least commonly used. Please read about it in above mentioned document.
Redirect URI's:
Now, as far as Redirect URI's are concerned, they are needed only in Authorization Code or Implicit grant types (Not sure about Client Credentials one, somebody please enlighten me on this in comments).
Redirect URI is given so that the Resource Server knows where to send the access token. Imagine if you are implementing Facebook login. In that case you will go to developers.facebook.com and register your application (like you did with django-oauth-toolkit), while registering your application, you will specify a Redirect URI.
Specifying a Redirect URI is a way of saying. "Hey Facebook, send the access token on this URI". So if you set Redirect URI something like https://your_domain_name.com/token/facebook/, Facebook will redirect to your specified Redirect URI at the end of Oauth2 process and give Access Token in the form of GET parameter, like https://your_domain_name.com/token/facebook/?token=some_long_string&some=other_parameters.
Related
I have a backend running Django 1.7 and a front-end developed separately with Bootstrap. The front-end talks to the backend through a REST API that I want to protect with OAuth2.
The question is: which grant type should I use? I trust the people working on the front-end but it does not mean I trust Javascript :-) I can't decide whether I should choose the Implicit grant or the Resource owner password-based.
Any experienced advice?
Especially when working with an API that is not on the same domain or server as your front end, it's usually better to use something like the web application flow for OAuth 2. This is typically referred to as the implicit grant, and uses the grant_type of token.
This way you won't need to worry about sending credentials across the wire, like you would need to for the resource owner password credentials grant. Along the same lines, you also don't have to deal with hiding private keys for the authorization code grant.
With the implicit grant, only the OAuth token must be stored on the local machine. This should be better, as the token should be able to be revoked quickly in the event that the token become public or something else forces it to be invalidated. The user should be logged in on the API server when the authorization request is made, but most OAuth providers support a custom login page that can be used as well.
With the password credentials grant, both the username and password must be stored on the local machine which requires you to additionally secure them. They are also considerably more difficult to revoke if the need arises.
I'm going to make a REST web service with many resource servers (implemented in different programming languages) and one authorization server.
My question is about token validation in the resource servers. Let's say that a resource server cannot connect to the database and check the token info there.
I have read this thread: OAuth v2 communication between authentication and resource server
And I like the idea to make an API in the authorization server, which will be responsible to "resolve" tokens. For example: https://oauth.example.tdl/tokeninfo?token=tokentovalidate
So my question: Should the /tokeninfo resource be "public"? I mean everyone who knows this endpoint will be able to validate tokens..
Wouldn't it be better to make this "private"? I mean https://oauth.example.tdl/tokeninfo?access_token=valid_token&token=tokentovalidate
But then my resource server will have to authorize itself before validating tokens.. too many requests, I think..
If you know more strategies to validate tokens between resource server and authorization server - tell me, because I'm pretty new to OAuth.
Should the token verification API be public?
In terms of authentication, if should of course be an authenticated API, and the access token that you use to call it is the access token you want to verify. RFC 6750 explains how to do that. Typically, the token is sent in the Authorization header, or as a Uri query parameter.
Alternatively, for more security, you require the client id and client secret to secure the call, either by passing them as parameters, either by obtaining an access token for the client using the Client Credentials Grant.
Be careful what information you return from the API. You should only return information that does not require a specific scope that has to be authorized by the resource owner.
For a real life example, see the Google implementation or the implementation from The Identity Hub. For the Facebook implementation, see the section "Confirming identity" on Manually Build a Login Flow.
We have a central RESTful webservices application that exposes data to many different clients (parsers, web applications, touch applications, etc). The clients have different means for authenticating users, some LDAP, others not. Regardless, the RESTful application leaves the authentication of the end-user to the client, and simply authenticates the client making the request. The client will have a username and password in LDAP, along with a list of acceptable IP addresses from which the client can access the RESTful application.
Here is the tricky part: the RESTful application must audit every request with the end-user's username. Furthermore, in certain circumstances (depending on the client) the RESTful application will need the end-user's username and password for accessing a third-party application. So, every request from the client will have authentication credentials for the client itself and the end-user accessing the client.
Here comes the question. Would it be best to put the client's credentials in Basic Auth, and pass the end-user's credentials via an encrypted SALT request parameter? Or, should the client put both sets of credentials in the Basic Auth (i.e. system~username:systempwd~userpwd) and parse them out into two sets of tokens that are then authenticated. Or, another solution that is better than either of these two?
This sounds pretty much like OAuth2's "Resource Owner Password Credentials Grant" - see https://www.rfc-editor.org/rfc/rfc6749#section-4.3. You pass application/client credentials in the Authorization header and client information in the body encoded using x-www-url-encoded. Do that once at the beginning of the session and then depend on a bearer token in the authorization header after that. All of that is described in the RFC. Remember to use SSL/TLS to encrypt the credentials.
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.
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:
resource owner (the user in your case)
resource server (your api)
client (the apps you talk about)
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.
I am building a web application with a services layer. The services layer is going to be built using a RESTful design. The thinking is that some time in the future we may build other applications (iPhone, Android, etc.) that use the same services layer as the web application. My question is this - how do I implement login? I think I am having trouble moving from a more traditional verb based design to a resource based design. If I was building this with SOAP I would probably have a method called Login. In REST I should have a resource. I am having difficulty understanding how I should construct my URI for a login. Should it be something like this:
http://myservice/{username}?p={password}
EDIT: The front end web application uses the traditional ASP.NET framework for authentication. However at some point in the authentication process I need to validate the supplied credentials. In a traditional web application I would do a database lookup. But in this scenario I am calling a service instead of doing a database lookup. So I need something in the service that will validate the supplied credentials. And in addition to validating the supplied credentials I probably also need some sort of information about the user after they have successfully authenticated - things like their full name, their ID, etc. I hope this makes the question clearer.
Or am I not thinking about this the right way? I feel like I am having difficulty describing my question correctly.
Corey
As S.Lott pointed out already, we have a two folded things here: Login and authentication
Authentication is out-of-scope here, as this is widely discussed and there is common agreement. However, what do we actually need for a client successfully authenticate itself against a RESTful web service? Right, some kind of token, let's call it access-token.
Client) So, all I need is an access-token, but how to get such RESTfully?
Server) Why not simply creating it?
Client) How comes?
Server) For me an access-token is nothing else than a resource. Thus, I'll create one for you in exchange for your username and password.
Thus, the server could offer the resource URL "/accesstokens", for POSTing the username and password to, returning the link to the newly created resource "/accesstokens/{accesstoken}".
Alternatively, you return a document containing the access-token and a href with the resource's link:
<access-token
id="{access token id goes here; e.g. GUID}"
href="/accesstokens/{id}"
/>
Most probably, you don't actually create the access-token as a subresource and thus, won't include its href in the response.
However, if you do so, the client could generate the link on its behalf or not? No!
Remember, truly RESTful web services link resources together in a way that the client can navigate itself without the need for generating any resource links.
The final question you probably have is if you should POST the username and password as a HTML form or as a document, e.g. XML or JSON - it depends... :-)
You don't "login". You "authenticate". World of difference.
You have lots of authentication alternatives.
HTTP Basic, Digest, NTLM and AWS S3 Authentication
HTTP Basic and Digest authentication. This uses the HTTP_AUTHORIZATION header. This is very nice, very simple. But can lead to a lot of traffic.
Username/Signature authentication. Sometimes called "ID and KEY" authentication. This can use a query string.
?username=this&signature=some-big-hex-digest
This is what places like Amazon use. The username is the "id". The "key" is a digest, similar to the one used for HTTP Digest authentication. Both sides have to agree on the digest to proceed.
Some kind of cookie-based authentication. OpenAM, for example, can be configured as an agent to authenticate and provide a cookie that your RESTful web server can then use. The client would authenticate first, and then provide the cookie with each RESTful request.
Great question, well posed. I really like Patrick's answer. I use something like
-/users/{username}/loginsession
With POST and GET being handled. So I post a new login session with credentials and I can then view the current session as a resource via the GET.
The resource is a login session, and that may have an access token or auth code, expiry, etc.
Oddly enough, my MVC caller must itself present a key/bearer token via a header to prove that it has the right to try and create new login sessions since the MVC site is a client of the API.
Edit
I think some other answers and comments here are solving the issue with an out-of-band shared secret and just authenticating with a header. That's fine in many situations or for service-to-service calls.
The other solution is to flow a token, OAuth or JWT or otherwise, which means the "login" has already taken place by another process, probably a normal login UI in a browser which is based around a form POST.
My answer is for the service that sits behind that UI, assuming you want login and auth and user management placed in a REST service and not in the site MVC code. It IS the user login service.
It also allows other services to "login" and get an expiring token, instead of using a pre-shared key, as well as test scripts in a CLI or Postman.
Since quite a bit has changed since 2011...
If you're open to using a 3rd party tool, and slightly deviating from REST slightly for the web UI, consider http://shiro.apache.org.
Shiro basically gives you a servlet filter purposed for authentication as well as authorization. You can utilize all of the login methods listed by #S.Lott, including a simple form based authentication.
Filter the rest URLs that require authentication, and Shiro will do the rest.
I'm currently using this in my own project and it has worked pretty well for me thus far.
Here's something else people may be interested in.
https://github.com/PE-INTERNATIONAL/shiro-jersey#readme
The first thing to understand about REST is that its a Token based resource access.Unlike traditional ways, access is granted based on token validation. In simple words if you have right token, you can access resources.Now there is lot of whole other stuff for token creation and manipulation.
For your first question, you can design a Restfull API. Credentials(Username and password) will be passed to your service layer.Service layer then validates these credentials and grant a token.Credentials can be either simple username/password or can be SSL certificates. SSL certificates uses the OAUTH protocol and are more secure.
You can design your URI like this-
URI for token request-> http://myservice/some-directory/token?
(You can pass Credentilals in this URI for Token)
To use this token for resource access you can add this [Authorization:Bearer (token)] to your http header.
This token can be utilized by the customer to access different component of your service layer. You can also change the expiry period of this token to prevent misuse.
For your second question one thing you can do is that you grant different token to access different resource components of your service layer. For this you can specify resource parameter in your token, and grand permission based on this field.
You can also follow these links for more information-
http://www.codeproject.com/Articles/687647/Detailed-Tutorial-for-Building-ASP-NET-WebAPI-REST
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
I have faced the same problem before. Login does not translate nicely to resource based design.
The way I usually handle it is by having Login resource and passing username and password on the parameter string, basically doing
GET on http://myservice/login?u={username}&p={password}
The response is some kind of session or auth string that can then be passed to other APIs for validation.
An alternative to doing GET on the login resource is doing a POST, REST purists will probably not like me now :), and passing in the creds in the body. The response would be the same.