How to exchange OAuth2 authorization codes for access tokens received from a client (Ember) in Express? - express

I'm using ember-simple-auth and torii to handle client-side OAuth2 authentication against Facebook and Google in an Ember app I'm building. I receive an authorization code from that process.
I want to send that code from the client to my REST API and exchange them for access tokens to get their user ID so I can figure out what information they should have access to.
Then, I want to put the user ID into a JSON web token that the client can send me in subsequent requests for data from the BE app.
My Problem: All examples I've found of using Passport for OAuth2 authentication rely on redirecting the user on the server side and using callbacks rather than just exchanging an already-provided authorization code.
What am I missing? This seems like something many apps would need to do.

Assuming a compliant OAuth 2.0 implementation, exchanging an authorization code for an access token is accomplished by performing a POST request to the token endpoint URL and providing the following parameters using the application/x-www-form-urlencoded format:
grant_type - Must be set to authorization_code.
code - Will contain the value of the code you have.
redirect_uri - Must be included and the value match, if it was also included in the request to obtain the authorization code.
Additionally, depending on the client you'll have to either provide the client_id parameter if the client was not issued credentials or if the client has credentials you need to perform client authentication, which can be done by passing an HTTP Basic authentication header containing the identifier and the secret.
An example, using unirest, but easily adapted to other HTTP clients:
unirest.post(tokenEndpointUrl)
.headers({
'Accept': 'application/json',
'Content-type': 'application/x-www-form-urlencoded'
})
.auth({
user: clientId,
pass: clientSecret
})
.send(`redirect_uri=${redirectUrl}`)
.send(`code=${code}`)
.send('grant_type=authorization_code')
.end(function (response) {
// Handle response
});
Although the fundamentals will probably not change, check each provider documentation, because they may have extensions put in place or be more flexible in how you can provide the info. For example Auth0 and I think Google is the same will also allow you pass the parameters in a JSON encoded body instead of just in application/x-www-form-urlencoded format.
Update:
Specific authentication providers may implement additional libraries that simplify things for developers integrating with them. For example, Auth0 provides you with passport-auth0 that abstracts and simplifies the way you can integrate Auth0 authentication into your application.

Related

OAuth 2.0 token introspection questions

I'm trying to understand token introspection as I need to implement token introspection for OAuth 2.0. But authentication is so hard to understand... :-( So I've got a couple of questions:
(1) As far as I understand, a post-request (with the access token) is sent to the IP. This then returns whether the access token is valid or not, as well as further information such as the user name.
This looks like the official spec to me: https://www.rfc-editor.org/rfc/rfc7662 it says a post request is needed to validate the access token. Did I understand that correctly
(2) This looks like the corresponding dependency, is it? using using IdentityModel.AspNetCore.OAuth2Introspection
Whats the difference between Microsoft.AspNetCore.Authentication.JwtBearer?
(3) According to the spec only the access token is requied (https://www.rfc-editor.org/rfc/rfc7662#section-2.1)
This example does not pass it but the clientid and the clientsecret:
https://github.com/IdentityModel/IdentityModel.AspNetCore.OAuth2Introspection
services.AddAuthentication(OAuth2IntrospectionDefaults.AuthenticationScheme)
.AddOAuth2Introspection(options =>
{
options.Authority = "https://base_address_of_token_service";
options.ClientId = "client_id_for_introspection_endpoint";
options.ClientSecret = "client_secret_for_introspection_endpoint";
});
Why not?
(4) If I set the config right, .Net Core will do the post-request (for every incoming request to my api) for me automatically, right? (I also added the [Authorize]-Attribute)
(5) How can I get the user context?
(6) I implemented a small example but get a 500. I do not see any error output. How can I log the errors?
The following are some of my understanding and opinions:
(1) The token introspection endpoint needs to be able to return information about a token, so you will most likely build it in the same place that the token endpoint lives. The request will be a POST request containing just a parameter named "token".
(2) JWTs are typically validated locally on the resource server.
It's a technical detail that IdentityServer can also validate JWTs at the introspection endpoint. That could be used e.g. when the resource server does not have an appropriate JWT library (and you don't want to store reference tokens on the IS side).
(3) In my opinion, this appears to be a configuration requesting an access token. Access tokens are the thing that applications use to make API requests on behalf of a user. The access token represents the authorization of a specific application to access specific parts of a user’s data. The Client Credentials grant is used when applications request an access token to access their own resources, not on behalf of a user. Please check this link: Access Tokens.
(4) If you add the [Authorize] attribute to the method that requires authorization, if the configuration is correct, the .Net Core App will automatically request authorization from the authorization server with your information.
(5) Do you want to access end user context on resource server? Maybe this link can help you.
(6) For logging error messages, please refer to this link: How do I log authorization attempts in .net core.
Hope this can help you.

Update a Socrata dataset using app token and private in HTTP basic

I'm trying to write a script to update metadata on various datasets, using an authorized app. Using OAuth seems like the wrong approach (it's not a web-facing application for other users to use as themselves), and passing my own user name and password seems...icky.
The SODA API authentication documentation is pretty confusing:
All HTTP-basic-authenticated requests must be performed over a secure (https) connection, and should include an application token, which is obtained when you register your application. However, authentication [sic, should be "application"?] tokens are not strictly required when a request is authenticated. Authenticated requests made over an insecure connection will be denied.
Here is a sample HTTP session that uses HTTP Basic Authentication:
POST /resource/4tka-6guv.json HTTP/1.1
Host: soda.demo.socrata.com
Accept: */*
Authorization: Basic [REDACTED]
Content-Length: 253
Content-Type: application/json
X-App-Token: [REDACTED]
So:
Can you even use app token + secret token to authenticate with HTTP basic?
Which of the two "[REDACTED]" is the app token, and which is the secret token?
My guess (based on some testing) is that the answers are:
No
The first "[REDACTED]" is the Base64 version of username+password, the second one is the application token, which is not relevant to authentication.
Application tokens and secret tokens aren't actually tied to any sort of pre-baked user authentication. They're tied to your application, and are then used in OAuth to ensure that your app is what it claims to be when the user is passed through the OAuth workflow. Once the user authenticates, the app can retrieve an authentication token that is used to actually authenticate their requests.
What you're really looking for is a way to retrieve a "bearer token", which some API providers allow you to generate. This would allow you to basically "pre-OAuth" and get an authentication token without going through the full workflow. Unfortunately we're not one of them (yet) so you'll need to authenticate with plain old HTTP Basic and your username and password.
If you want a slightly-less-icky way to do that, I recommend registering a "bot" account that you grant only the necessary permissions on the necessary datasets. Then at least you're not baking your regular user credentials into your config. But keep in mind that even if we had bearer tokens, you'd be putting those into your config somewhere.
To answer your more specific questions:
No, because then one of them would have to be a bearer token, which they are not.
The Authorization header is the Base64 encoded username:password, while the X-App-Token is your application token. In this case the latter is just an extra header that would identify that request as having come from your app.
Thanks for your feedback on the docs - I'll clean them up and try to be more straightforward, and I'll definitely fix that typo.

OAuth resource owner password flow and HMAC

I have a web api application which implements the Resource Owner Password flow from OAuth specification. Everything works correctly.
Actually I configure everything in my WebApiConfig class by using an Authentication filter like this
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add( new HostAuthenticationFilter( OAuthDefaults.AuthenticationType ) );
As some of my customer asked for a different method of authentication I am evaluating to add a couple of features to my services but stil did not have clear how those features can work together.
In particular I cam across a link which explain in very easy words how to implement a HMAC authentication in web api.
Can I implement this authentication method and let the client to choose which one he want to use? Do they can cohesist together?
Yes, your web api service can send back multiple schemes in the WWW-Authenticate challenge. In your case it can send back 'bearer' and 'hmac' for example.
See also this question for more info on using multiple schemes.
BTW, it's not your web api service that supports Resource Owner Password flow. The client uses this flow to get a token from the authorization server that it can use in a bearer scheme with your service (resource server). HTH.

Why use Client Credentials flow?

I've been looking at using oauth2 client credentials grant to secure my API (all users will be trusted 3rd parties). I'm following the same approach as paypal here: https://developer.paypal.com/docs/integration/direct/paypal-oauth2/
However, I see that HTTP:// basic auth is used to acquire a bearer token. Then the bearer token is used to secure the API calls.
What I don't understand is, if you're going to trust TLS and http: basic auth to retrieve the bearer token - why not just use http: basic auth for the API calls? What is the benefit of using bearer tokens?
What am I missing?
Adding to what Ankit Saroch is saying, going the OAuth way with Tokens may open up other possibilities in the future; say you may want to extend the flow to include User information. By only validating tokens, this means you will probably not need to change the token validation (which is simple) in your service, but rather only the authentication and authorization steps.
But obviously you're right in what you are saying: The Client Credentials OAuth Flow is not more secure than simply using techniques like API Keys or Basic Authentication. All of those rely on the Client being confidential (it can keep its credentials to itself).
The OAuth Spec (https://www.rfc-editor.org/rfc/rfc6749#section-2.1) talks about these Client Types. In total, it's worth reading the spec actually.
As per The OAuth 2.0 Authorization Framework: Bearer Token Usage
The access token provides an abstraction, replacing different
authorization constructs (e.g., username and password, assertion) for
a single token understood by the resource server. This abstraction
enables issuing access tokens valid for a short time period, as well
as removing the resource server's need to understand a wide range of
authentication schemes.
The server that is authorizing the request and giving you the Bearer Token, may be different from the server that actually controls the resources that you are trying to access.
As per the RFC, they have been shown as two different entities. The one giving you the Bearer Token is Authorization Server and the one serving the resources is Resource Server.

Adding OAuth 2.0 authentication to a RESTful API

I have an API that requires authentication via OAuth 2.0. I originally anticipated using HWIOAuthBundle, however from investigation this is more to do with hooking up 3rd parties into Symfony's security/auth mechanism and does not provide the required mechanism for validating OAuth 2.0 Authorization headers.
I then found some information about FOSOAuthServerBundle which enables an application to become it's own OAuth 2.0 provider as well as providing the required security mechanisms to validate Authorization headers.
However the problem is that I would like integrate the OAuth 2.0 provider (authorisation server) in an external application (which contains the user base) and not include it within the API. Which will provide some mechanism for performing the token verification against this external app via (another) RESTful API.
Points:
RESTful API requires OAuth 2.0 authentication.
OAuth 2.0 authorisation server to be situated in a separate application.
I feel I should use Implicit grant and call the authorization server on each request to validate that the token is correct.
Is my thinking correct?
As far as I undesratnd your requirement, you require to authenticate your APIs via external OAuth Authorization Server:
Client needs to provide the access token retrieved in the above steps
along with the request to access the protected resource. Access token
will be sent as an authorization parameter in the request header.
Server will authenticate the request based on the token.
If token is valid then client will get an access to protected resource otherwise access is denied.
here is an example which might help you to achieve your requirement. Check this document .
Or simply, you can do with Jersey and Oauth
Also, you can check Apache Oltu and figure out the way to achieve your requirement.
A lot of the big companies like Google, Facebook etc have a separate authorization server from the API server. Check out Google's OAuth authorization flow below
You can also check Google's OAuth Documentation for the details.
So all you would need to do is implement a OAuth Provider so that you can authorize against that provider. There's a list of libraries available on the OAuth website: http://oauth.net/code. You can specifically look here; there is an example for running an OAuth Service Provider in Java.
oAuth can most definitely be a server other than your application server. Below is a picture of what the authentication sequence would look like:
-- Obviously, if the forum can't decode or validate the token, the forum would return a 401 status code instead of a 200 status code.
As long as your oAuth server & the Forum share the same public key, you're more than okay with splitting your oAuth Server & your application.
In fact, take a look at jwt.io. Paste the token you get from the oAuth server into there. It should be able to decode the token right away. Then, you can put your public key into the 'secret' text box to verify the token is verified.
Your application (Forum, in this example) should be able to do the same:
1) Grab the token from the Authorization header of the request
2) Decode the token
3) Check the expire date
4) Verify the token using the oAuth's public key
5) Return successful status code or a failure status code