When an OAuth signed request is made to a Rails 3 app, I can see the OAuth consumer key in amongst the other values in request.headers["HTTP_AUTHORIZATION"]. What is a better way to access it? I'm using the OAuth gem.
According to this section in the OAuth specification, the Authorization header is the preferred way of sending OAuth protocol parameters. The specification does make allowances for sending protocol parameters in a form encoded body or in the request URI, if the request meets certain requirements.
To answer your question: parsing the Authorization header is a must for any OAuth provider. But you may also look for it (and other protocol parameters) amongst "normal" parameters, you will never find them in more than one place,
Related
Sources such as this Okta sponsored site (see "Per-Request Customization" section) mention that the redirect_uri parameter of a autorization request SHOULD NEVER have a dynamic query part (ex: for session matching uses).
Quote:
The server should reject any authorization requests with redirect URLs
that are not an exact match of a registered URL.
Our OAuth AZ provider is BIG-IP F5. We are setting it up, and they seem to comply with the above view.
Our client is a web application built elsewhere, and they seem to not follow the above rule.
Here is a complete representation of the Authorization Endpoint (redacted):
https://ourownF5host.ca/f5-oauth2/v1/authorize?client_id=theIDofOurClient&redirect_uri=https%3A%2F%2FourClientAppHostname%2FClientRessource%2FRessource%3FSessionId%3D76eab448-52d1-4adb-8eba-e9ec1b9432a3&state=2HY-MLB0ST34wQUPCyHM-A&scope=RessourceData&response_type=code
They use a redirect_uri with a format similar to (I don't urlencode here, for simplicity's sake) : redirect_uri=https://ourClientAppHostname/ClientRessource/Ressource?SessionId=SOMELONGSESSIONID, with the SOMELONGSESSIONID value being DIFFERENT for each call.
We dug DEEP into RFC6749 (OAuth2), and found this in section 3.1.2.2:
The authorization server SHOULD require the client to provide the
complete redirection URI (the client MAY use the "state" request
parameter to achieve per-request customization). If requiring the
registration of the complete redirection URI is not possible, the
authorization server SHOULD require the registration of the URI
scheme, authority, and path (allowing the client to dynamically vary
only the query component of the redirection URI when requesting
authorization).
What I understand, and would like to validate here, is that the first source, Okta and F5 accept ONLY the first part of the rule above, and require the redirection uri to be COMPLETELY registered without any dynamic part.
Am I right to affirm that they (Okta and F5) DO NOT comply with the second part of the excerpt, citing that they should "allow(ing) the client to dynamically vary
only the query component of the redirection URI when requesting
authorization" ?
OR, is there any kind of official correction/evolution of the RFC6749, that warrants both companies design position ?
TL;DR:
No, the redirect uri must be static for security reasons. If the client needs to keep a state between the authorization request and its asynchronous response, use the OAuth 2.0 state parameter.
Long version :
RFC6749 (the initial OAuth 2.0 specification) has been published in 2012 and OAuth security landscape has evolved a lot since then.
RFC6819, an OAuth 2.0 security review from 2013 already mentioned that refusing dynamically crafted redirect uris was a good way to protect against XSS and client impersonation attacks.
OpenID Connect, from 2014, a commonly used extension of OAuth 2.0 with authentication capabilities, already takes that recommendation into account and mandates exact string matching for all redirect uris.
The current draft recommendation for OAuth 2.0 Best Security Practice confirms that by enforcing redirect_uris preregistration and mandating the use simple string comparison by the AS when validating the redirect_uri passed in the request. So a dynamic redirect_uri must not be used.
Your client definitely makes a wrong move by using the redirect_uri as a "state keeper" between the Authorization request and response, by using a dynamically crafted SessionID attribute inside the redirect_uri. OAuth2.0 has a dedicated authorization request parameter for that purpose, which is "state". The client should use it. The AS will append that state in the parameters of the redirect_uri when it issues the response, so the client will be able to find back this state inside the response.
The proper authorization request would be:
https://youras/authorize?client_id=your_client_id&response_type=code&state=SOMELONGSTATE&redirect_uri=https%3A%2F%2Fsomehost%2Fauthcallback
The response will look like:
https://somehost/authcallback?state=SOMELONGSTATE&code=anazcode
This way the redirect_uri is static, so a simple string comparison is enough to validate that uri on AS side. Any algorithm more complex than simple string comparison would be subject to security flaws.
It appears there's two things mixed up here: the URL you refer to:
https://somehost/authcallback?state=SOMELONGSTATE&scope=someobjecttype&response_type=code
suggests that you mixed up the Redirect URI (aka. callback URL, as suggested by the pathname in the URL) of the Client with the Authorization Endpoint of the Authorization Server.
Only the Authorization Endpoint would take parameters as suggested and may contain e.g. a dynamic state value. The Redirect URI of the Client would not contain e.g. response type.
A redirect_uri parameter can be added to the the authorization request, which would then have to be matched in the way that you described. After confirming the match, the Authorization Server will redirect back to the Redirect URI, adding the code and state parameters.
Update (after the question changed):
OAuth 2.0 RFC6749 allows a dynamic (SessionId) parameter though it is not considered best practice. If however your client is an OpenID Connect Client, this is not allowed since the OpenID Connect spec (a "profile" of OAuth 2.0) locks down the Redirect URI matching to "exact", in which case you'd have to configure all possible SessionIds.
I am trying to do a request my Netsuite RESTlet using Alamofire (SWIFT) but I meet several difficulties:
In the documentation it's specify the different parameters needed (see below).
DOCUMENTATION:
An OAuth 1.0 RESTlet authorization header requires the data described in the following table. Some of these values can be obtained from the NetSuite UI. Other values must be calculated. Typically, your integration should include logic to identify these values and generate the finished header. Follow the OAuth 1.0 protocol to create the authorization header.
However in postman I am using extra parameters (consumer Secret and the Token Secret) and it's works if I remove them it doesn't works
To finish when i check the Authorization header generated by postman, I see only the specify parameters in the documentation :
OAuth realm="my realm",oauth_consumer_key="myConsumerKey",oauth_token="myAccessToken",
oauth_signature_method="HMAC-SHA1",oauth_timestamp="1543488570",
oauth_nonce="ERxdLbUfkeh",oauth_version="1.0",oauth_signature="UeqmxAyeUqtPoICLo%2FARsQE8B1E%3D"
If someone can explain me this, I could implement TBA authentification in my Application but for now I need to understand better this authentification.
I also spend a few hours trying to make it work. In my case I wasn't adding the account ID to the realm param. Here a picture of what I ended with:
Here where you can get the account ID:
I hope it helps
The explanation of why the consumer secret and the token secret are needed by Postman to generate the token is shown in SuiteAnswer 42019 - as referenced in the Notes section beside oauth_signature in your screenshot above. From that page:
Sign the result string from step 5 using the consumer secret and token secret concatenated using '&' (For this case, HMAC-SHA1 or HMAC-256).
In other words, Postman uses the secrets to generate the output which authenticates your credentials - you cannot generate the oauth_signature correctly without them.
I ran into a lot of issues with NetSuite broken RESTlet/TBA connections as well. I did build this out in our software to help out customers. You can see the methods I used in the article below.
Using NetSuite TBA by Calling a RESTlet from an HTTP Source or Target
I am confused that there seems to be no standard way to specify the audience for an access token when sending an authorization request to an authorization server.
OAuth2 specifies access tokens as opaque strings; there is only one mention of 'audience' in the spec, to say that access tokens could be 'audience-restricted'.
Many recent authorization server implementations seem to produce JWT access tokens, and JWT specifies the audience (aud) claim.
As far as I find:
- Auth0 uses an 'audience' parameter
- Connect2id uses a 'resource' parameter
- Identity Server uses a fixed issuer-based value for 'aud' claim, and assumes that scopes are enough - however, this does not fit all use cases.
- The excellent 'OAuth2 in Action' book shows an example with a resource server URI in the 'aud' claim, but doesn't say where it comes from.
So, how to get an access token for a specific audience (resource server, API,...) in a standard way?
I think you are right. There are a couple of guidelines available.
The OAuth 2.0 Authorization Framework: Bearer Token Usage
OAuth 2.0: Audience Information (draft-tschofenig-oauth-audience-00.txt)
OpenID connect a clear defined "aud" parameter as:
REQUIRED. Audience(s) that this ID Token is intended for. It MUST
contain the OAuth 2.0 client_id of the Relying Party as an audience
value. It MAY also contain identifiers for other audiences. In the
general case, the aud value is an array of case sensitive strings. In
the common special case when there is one audience, the aud value MAY
be a single case sensitive string.
"Proposed Standard" way of requesting an Access Token for a specific Audience/API/Resource Server is by using the resource query parameter on the Authorization Request.
When the "resource" parameter is used in an authorization request to
the authorization endpoint, it indicates the identity of the
protected resource(s) to which access is being requested.
resource
Indicates the target service or resource to which access is being
requested. Its value MUST be an absolute URI
RFC8707: Resource Indicators for OAuth 2.0
https://datatracker.ietf.org/doc/html/rfc8707#section-2
You mentioned the Tschofeniq draft in your comment on the accepted answer, but actually it looks like that doc is actually does support using the audience field:
The audience URI MUST be an absolute URI as defined by Section 4.3 of [3]. It MAY include an "application/x-www-form-urlencoded" formatted query component
In fact it speaks quite strongly that this step is important and that it should be done in exactly that manner:
Step (2): When the client interacts with the token endpoint to obtain an access token it MUST populate the newly defined audience parameter ...
So it seems Auth0 is probably on the right track with the direction they took. And as you pointed out in your comment, the aud field is for the response, not the request (common libraries like jsonwebtoken in NodeJs set fields like this (along with sub, jti, and iss) when you decode a JWT.
I already have an account in Twitter Dev, which allowed me to get a Consumer Key and secret, which I used to generate my token. Now I am trying to send token in request for Twitter API by using the operators "Get Page", "Jason to XML" and "Write Document". However, I do not know which URL to write in the "Get Page" operator. Is it Request token URL Authorize URL or Access token URL ?
In general the request URL contains the REST API call, while you are providing your authorization credentials e.g. via request properties in the HTTP header, OAuth mechanisms and the like. An REST API call is build up on a base URL awaiting a call, in case of twitter https://api.twitter.com/1.1/search/tweets.json, combined with a state and HTTP options forming your request. If your searching for tweets from a given user account (like #twitterapi) your request URL part would look like q=%40twitterapi. Here a key q is given with the value %40twitterapi, where %40 is a representation of the '#' symbol.
Providing key-value-pairs via GET using the HTTP protocol is initialized with a leading '?'. Hence your REST request would look like this:
https://api.twitter.com/1.1/search/tweets.json?q=%40twitterapi. This example is taken from the Twitter documentation.
That's about the URL.
For the RapidMiner site, I'd try to use the Enrich Data by Webservice operator. You can fill in the url parameter with your request URL and set the HTTP header for using an authentication token using the request properties parameter. As a property use Authorization and for the value you use a string starting with Bearer followed by your token. So a potential value could be Bearer 943582034-IH3k6hlskfdj32l4hks.
You can choose betweent different query types (e.g., String Matching, Regular Expression and others) to define the handling of the received payload given as an response to your request.
Before playing around with the operator, you can try using a tool like Postman (Chrome Plugin) or HTTPrequester (Firefox Add-on) to work directly with the HTTP GET request and its response.
Sorry for not including more references, but Stackoverflow doesn't allow for more than two if your reputation is below 10...
I concur with the above - use the Enrich Data via Webservice operator. You'll need to download the Web Mining extension in order to see it. If you re-post on the RapidMiner user community forum, you may get more RapidMiner-specific help as well.
I feel silly even asking this question, but am at the limits of my understanding, and am hoping someone can provide some context.
I'm looking at the following (https://stormpath.com/blog/token-auth-for-java/) which states:
The access_token is what will be used by the browser in subsequent requests... The Authorization header is a standard header. No custom headers are required to use OAuth2. Rather than the type being Basic, in this case the type is Bearer. The access token is included directly after the Bearer keyword.
I'm in the process of building a website, for which I'll be coding both the back-end REST service, as well as the front-end browser client. Given this context, why do I need to follow any of the guidelines given above? Instead of using the access_token, Authorization and Bearer keywords, what's stopping me from using any keywords I like, or skipping the Bearer keyword entirely in the header? After all, as long as the front-end and back-end services both read/write the data in a consistent manner, shouldn't everything work fine?
Are the keywords and guidelines given above merely best-practice suggestions, to help others better understand your code/service? Are they analogous to coding-styles? Or is there any functional impact in not following the above guidelines?
Given this context, why do I need to follow any of the guidelines given above?
Because they are standardized specifications that everyone is meant to conform to if they want to interact with each other.
Instead of using the access_token, Authorization and Bearer keywords, what's stopping me from using any keywords I like, or skipping the Bearer keyword entirely in the header?
Nothing, except that it won't be OAuth anymore. It will be something custom that you created for yourself that noone else will understand how to use, unless you publish your own spec for it.
After all, as long as the front-end and back-end services both read/write the data in a consistent manner, shouldn't everything work fine?
Who is to say that you alone will ever write the only front-end? Or that the back-end will never move to another platform? Don't limit yourself to making something custom when there are open standards for this kind of stuff.
Are the keywords and guidelines given above merely best-practice suggestions, to help others better understand your code/service?
No. They are required protocol elements that help the client and server talk to each other in a standardized manner.
Authorization is a standard HTTP header used for authentication. It has a type so the client can specify what kind of authentication scheme it is using (Basic vs NTLM vs Bearer, etc). It is important for the client to specify the correct scheme being used, and for the server to handle only the schemes it recognizes.
Bearer is the type of authentication that OAuth uses in the Authorization header. access_token is a parameter of OAuth's Bearer authentication.
If you use the Authorization header (which you should), you must specify a type, as required by RFCs 2616 and 2617:
Authorization = "Authorization" ":" credentials
credentials = auth-scheme #auth-param
auth-scheme = token
auth-param = token "=" ( token | quoted-string )
So, in this case, Bearer is the auth-scheme and access_token is an auth-param.
Are they analogous to coding-styles?
No.
Or is there any functional impact in not following the above guidelines?
Yes. A client using your custom authentication system will not be able to authenticate on any server that follows the established specifications. Your server will not be able to authenticate any client that does not use your custom authentication system.