I have an angular app that I need to redirect outside to a server side html page, so I thought I could just use a standard <a> tag with target='_self' to redirect the angular app to my server side page. This actually works fine, however, I have a rails backend that checks for auth token before serving up any content.
This requires a auth token to be sent in the header of the http request which I am setting in a cookie, and angular grabs automatically with the $http service for ajax requests, but I can't seem to get the same thing to happen on a standard link.
Can/How do you add an auth token to a normal link before it is sent off?
When the browser is making the HTTP request and not your JavaScript code, you cannot add a custom header with your token value. See Adding http headers to window.location.href in Angular app for a similar question.
However, if this value is already being sourced from a cookie, can your backend just read that cookie value (or use some filter in the http request chain to transfer the cookie to a header)?
Related
I saw in a few places that Imlicit flow clients use iframe to get a new token silently, without user interaction. Why is that? Why can't the client just send a GET request to the authorization server and retrieve the token from the returned HTTP 301 response?
I saw iframe mentioned in these places:
https://learn.microsoft.com/en-us/azure/active-directory/develop/reference-third-party-cookies-spas
https://auth0.com/docs/authenticate/login/configure-silent-authentication
I found this post: OAuth2 Implicit Flow - IFrame Refresh Identity. It says that the request sent from iframe carries a cookie with it. Is it not possible to attach such a cookie from a JS request?
I am learning OAuth 2.0.
In both code flow and implicit flow (response_type = code or token). The temporary code or access_token is placed in the URL fragment (after the #) instead of in the query string.
According to this doc: https://developer.okta.com/blog/2018/05/24/what-is-the-oauth2-implicit-grant-type:
If the user approves the request, the authorization server will redirect the browser back
to the redirect_uri specified by the application, adding a token and state to the fragment
part of the URL.
For example, the user will be redirected back to a URL such as:
https://example-app.com/redirect
#access_token=g0ZGZmNj4mOWIjNTk2Pw1Tk4ZTYyZGI3
&token_type=Bearer
&expires_in=600
&state=xcoVv98y2kd44vuqwye3kcq
Note the two major differences between this and the Authorization Code flow: the access token is returned
instead of the temporary code, and both values are returned in the URL fragment (after the #) instead
of in the query string. By doing this, the server ensures that the app will be able to access the value
from the URL, but the browser won’t send the access token in the HTTP request back to the server.
What exactly does it mean by
the server ensures that the app will be able to access the value from the URL, but the browser won’t send the access token in the HTTP request back to the server.
?
Of course the code/ access_token value is accessible from the URL.
The Auth server builds up the url and put it in location header of the HTTP response, which is sent back to the user's web browser. The web browser then take values from the response, and send new http requests to the application instead of the Auth server. So, of course the user's web browser is not sending HTTP request back to the server.
It has nothing to do with where the access token is placed in the response (from Auth server back to the user's web browser). The web browser simply starts talking to the application again instead of the Auth server.
This explanation just does not make much sense to me.
The code flow returns an authorization code to the browser in the query string. You then make a POST request to swap the code for tokens.
https://www.example.com?code=xxx&state=yyy
Implicit flow is now deprecated since it can reveal tokens in the browser history or server logs. It dates back to when browsers did not have CORS capabilities to make cross orign POST requests to the Authorization Server.
Data in client side hash fragments does not get sent to servers and the implicit flow used this as a partial mitigation for sensitive data. Eg the zzzz below does not get sent to the web server if you type this in a browser.
https://www.example.com#zzzz
If you are new to OAuth and OpenID Connect, start with code flow + PKCE, and understand these messages.
SWAPPING THE CODE FOR TOKENS
This is often done via a back end component that completes the flow, so that a client secret can be attached (a browser cannot keep secrets). This back end component can then do either of these:
Return access tokens to the browser
Issue secure cookies to the browser
Once done, the front end has a credential with which it can call the main back end (eg APIs), so that the back end knows the user identity.
CODE EXAMPLE
In 2021 the cookie option is considered more secure, but it also requires a more complex flow. All of the complexity involved originates from the browser being a hostile place to execute code - there are lots of security threats there. Here is some example code that uses cookies:
OAuth calls from an SPA
API calls from an SPA
I'm updating my desktop app, an Imgur client, for the upcoming deprecation of code/pin auth methods, by using a local web server to catch the redirect_url from the browser after the user authorizes access to the app. So I launch the URL in the browser, the user accepts, then Imgur redirects to
http://localhost:7710/myapp?state=auth#access_token=....&expires_in=
etc
but the browser cuts the URL at # so all the variables are missing, and my app only receives "state=auth"
from Imgur's API docs:
The response_type Parameter token: This authorization flow will
directly return the access_token and refresh_token via the redirect
URL you specified during registration, in the form of hash query
string parameters. Example:
http://example.com#access_token=ACCESS_TOKEN&token_type=Bearer&expires_in=3600
The code and pin response types have been deprecated and will soon no
longer be supported.
Imgur returns an access token to your application if the user grants
your application the permissions it requested. The access token is
returned to your application in the fragment as part of the
access_token parameter. Since a fragment (the part of the URL after
the #) is not sent to the server, client side javascript must parse
the fragment and extract the value of the access_token parameter.
Clearly they haven't thought this through for desktop applications, or am I missing something?
Imgur stuff looks non standard, since response_type=token is a basic version of the implicit flow, which used to be the solution for single page pps.
These days all UI based flows should use Authorization Code Flow (PKCE) and response_type=code.
Since your app is acting as a (loopback) web server it will not receive the hash fragment parameters, which are only available to JavaScript code running in a browser.
One option that would enable you to get the full URL would be to login via the system browser and to use a Private URI Scheme to call back to the app.
The above link is a visual blog post to explain how this works, in case it is of interest.
After reading through the oAuth 2.0 draft 23 I have a better understanding of how oAuth works, however one thing I'm not understanding is the request uri:
I've read the section in the draft and it explains the request uri needs to be an absolute url from the client but if I am making an android/iphone app then what must this value be as my app is not a website on a web server?
You can define your own custom URI scheme, say
myapp://oauthcallback
Now you setup your app to listen for this scheme (works on Android and on iOS). When your browser/webview then gets redirected after the authorization request, your app will start and you can handle the query parameters sent with the URI.
I'm creating a viewer app for Windows Phone 7. The app already handles the OAuth2 stuff and succesfully browses Google Doc's folder structure.
I use Google Documents List API 3. BTW browsing works perfectly without using request headers, instead I append the access_token to the request Uri.
Now the app needs to show files to the user, if possible without downloading them first. This means that I want to set the UI's Image.Source to the Uri of an image, the UI's MediaElement.Source to the Uri of a video and the BackgroundAudioPlayer.Track.Source to the Uri of an audio file. Obviously I can't use request headers in this scenario.
However it seems that simply appending the access_token to the download Uri doesn't work. The UI elements fail with generic error messages, and if I manually try with a web browser (which isn't logged in to Google) it shows an empty screen, a 401 error or it redirects to Google's login page.
Is it possible to download/stream a Google Data entry just by defining the Uri? If yes, what does the Uri need to look like?
Support for authorization using the access_token URL parameter has not been allowed on purpose for security reasons. Basically if a user would be to open a malicious file on a browser (e.g html containing some Javascript would suffice) the malicious code on the file could steal the access token in the URL and send it to a third party bad guy.
To access the file you need to authorize using "Authorization" HTTP header. Simply add an HTTP header to the request which is like:
Authorization: Bearer access_token_here