Single Page Web App & appropriate oauth authorization flow - oauth

I'm developing a singe page page app and from researching online it looks like the implicit oauth flow is most applicable. The concern i have is that I can't use refresh tokens and I do not want to have to request the user to login frequently.
I guess one solution is long lived access tokens ?

The Best Practice is to use the Authorization Code without client_secret and better to use Proof Key for Code Exchange by OAuth Public Clients
(PKCE) the Authorization Code. (Which allows Refresh Tokens)
The following show several OAuth 2.0 Providers and discussions using the Authorization Code (without client_secret) for SPA:
https://aaronparecki.com/oauth-2-simplified/#single-page-apps
https://www.oauth.com/oauth2-servers/oauth2-clients/single-page-apps/
https://www.ietf.org/mail-archive/web/oauth/current/msg16966.html
https://www.ietf.org/mail-archive/web/oauth/current/msg16968.html
https://www.ietf.org/mail-archive/web/oauth/current/msg16967.html

Related

In Oauth OpenID - Authorization code grant type, where will we exchange the "code" for "access token" and why?

In Oauth Open ID - Authorization Code grant type flow,
We will call the Oauth service provider with the client_id = '..', redirect_uri='...', response_type='code', scope='...', state='...'.
Then from Oauth Service Provider, we will get the authorization code instead of the token.
Q1. So what is the next step? Do we send the code to the back end where the token request will happen or will we call the Oauth service provider from the browser it self?
Q2. Why do we need this additional calls? what problem it is solving?
Q3 After the token is received, how we use it in a typical web application?
p.s: I have read lot of blogs, but unable to get the whole picture. Could you please help me?
Q1. In 2021 it is recommended to keep tokens out of the browser, so send the code to the back end, which will exchange it for tokens and issue secure SameSite HTTP Only cookies to the browser. The cookies can contain tokens if they are strongly encrypted.
Q2. The separation is to protect against browser attacks, where login redirects take place. An authorization code can only be used once but can potentially be intercepted - by a 'man in the browser' - eg some kind of plugin or malicious code. If this happens then the attacker cannot exchange it for tokens since a code_verifier and client_secret are also needed.
Q3. The token is sent from the browser to APIs, but the browser cannot store tokens securely. So it is recommended to unpack tokens from cookies in a server side component, such as a reverse proxy. This limits the scope for tokens to be intercepted in the browser, and also deals well with token renewal, page reloads and multi tab browsing.
APPROACHES
The above type of solution can be implemented in two different ways:
Use a website based technology that does OAuth work and also serves web content
Use an SPA and implement OAuth work in an API driven manner
Unfortunately OAuth / OpenID in the browser is difficult. At Curity we have provided some resources based on the benefit of our experience, and we hope that this provides a 'whole picture' view of overall behaviour for modern browser based apps:
Code
Docs

OAuth Code Authorization grant with PKCE but for app, not user

The OAuth2 spec defines a Client Credential grant for machine-to-machine authorization, where a user isn't involved. Identity is confirmed via a client secret. This isn't appropriate for a native client, such as a mobile application, because stored client secrets can't be guaranteed.
Mobile apps can make use of the OAuth Code Authorization grant plus Proof Key for Code Exchange (PKCE), which allows a dynamically generated secret. This is great if you need user authorization/authentication.
However, what if you just need to protect your API's resources so that only your mobile app can use it, but you don't track users? That is, I'd like to get an access token for my application, instead of for a user.
It seems like Code Authorization + PKCE would work great, if only both the login and consent screens could be disabled. Just return the auth code. I was hoping to find a way to do this in IdentityServer3, but haven't.
Is there a configuration or flow that allows this? Or am I making a security mistake?
EDIT
It further seems to me that using PKCE should allow for a flow with two backchannel calls, one to the authorize endpoint, the other to the token endpoint. Essentially, Code Authorization without the browser redirection. I know such a flow isn't in the spec, but am I right? Regardless, the question remains, how to authorize a mobile app using its own account, not a user's?

Can I use Oauth2 Authorization Code flow for a SPA (React app), if I have a server-side proxy?

After watching an obscene amount of tutorials on OAuth2, there is one best practice that everyone repeatedly states - if you have a React app (or Angular, or Ember) - you must use Implicit flow with it.
I understand that storing client credentials in publicly visible javascript would not work. However, my scenario is a bit different:
I'm only using Oauth2 for single sign on and token generation for microservices. I chose it instead of simply generating tokens, since well-supported third party libraries are built around the Oauth2 idea.
My idea is to have a React app, and a ASP.NET MVC app which serves the javascript and acts as a proxy for API requests. The user authenticates for the server-side app (by using Oauth2 authorization code flow).
Then if I need to retrieve data from an API, I call my ASP.NET MVC app from React (by sending a simple cookie). The MVC app holds the token without ever exposing it to the user's browser.
Obviously, when called, my MVC app then redirects the request to the necessary API, providing the bearer token.
To better understand why this is what I came up with, here are some requirements I've received that might be unusual:
I really don't want the access token to be shared - even if it's relatively short lived.
I also want to be able to limit each user account to 3 concurrent user sessions. Easy to do using cookies and server-side sessions.
I can't wrap my head around why this idea would be that bad. Is there any technical problem that might prevent this from working? Or maybe a security risk?
The authorization code flow returns an authorization code (like it says on the tin) that can then be exchanged for an ID token and access token. This requires client authentication using a client id and secret to retrieve the tokens from the back end and has the benefit of not exposing tokens to the User Agent.
This flow allows for long lived access (through the use of refresh tokens).
Clients using this flow must be able to maintain a secret.
Accordingly to your description, you have service-to-service authorization flow, and as your service are not exposing client secret key it is totally OK to use the Code flow. Moreover, you should use it to allow long lived tokens.

Using OAuth2 Implicit Flow(IdentityServer4), do users have to re-input password every expiration of access token?

I need to implement Authorization/Authentication for an Angular2 Client Side WebApp to talk to a Resource Server(WebApi).
I am investigating IdentiyServer4 and choosing a Grant Type / Flow. HERE
Resource Owner Password Credentials Grant(What we use now.) "This is so called “non-interactive” authentication and is generally not recommended".
Authorization Code & Hybrid <- Solution to Implicit Flow not allowing Refresh Tokens.(Seems fairly complex to me. But is this the way to go?)
Implicit Flow - Recommended for SPA's everywhere I look. But does not support Refresh Tokens..
With Implicit Flow, how do I not require the user of the SPA to have to type in a password every say 3600 sec? A recommended access_token lifetime. I presume there is something I do not understand about getting the new authorization URL.
Resources I have looked at.
IdentityServer4 Grant Types
Implicit Grant Flow for Client-Side Apps
A Guide To OAuth 2.0 Grants
SO - Oauth2 Implicit Flow with single-page-app refreshing access tokens
Thanks for the answer Scott. I have some reading to do.
Getting Started with IdentityServer4
When using the Implicit flow you can still use your own cookie lifetimes (ie longer than 3600 seconds). To get around access tokens expiring, you can use the fact that the user is still authenticated within IdentityServer to fetch another access token, without the need for refresh tokens.
The IdentityModel OpenID Connect JS Client does this by firing an event just before access token expiration and using an iframe to make a fresh authentication request to IdentityServer. If the user is still logged into IdentityServer (which has a different, typically longer lived cookie than your own client application), then IdentityServer sends back fresh tokens just like a normal authentication request. This happens in the background with no interaction from the user and no interruption.
Check out the automaticSilentRenew functionality in this library for implementation specifics.
By the way, the Implicit, Authorization Code and Hybrid grant types, in the case of IdentityServer, are OpenID Connect grant types. Resources referring to the OAuth versions may not apply to your use case.

OAuth 2.0 Single-use Access Token for unauthenticated user via IdentityServer4

I apologies in advance for incorrect use of oauth terms.
I have 4 "parties" as follows (intentionally not using oauth terms where possible):
End-user in a browser (javascript)
Our website (aspnet)
Our web api (aspnet)
Our auth server (aspnet utilising identityserver 4)
My usage scenario is that we only want the API to be called by a browser that has requested a page from the website first. Whilst the API doesn't release sensitive information, we would like to introduce a layer of complexity with regards to the API being spammed.
Our end user's will not be logged in.
I imagine such a flow being akin:
Browser requests a certain page from the website (one that will likely lead to js making an api call)
Website requests token from auth server
Auth server verifies token request came from website (the server itself)
Auth server returns a token to the website
Website returns page including the access token
Browser is able to make a request to api using token
Although convoluted, I believe this is at least similar to the Client Access Grant flow?
These tokens could then be throttled either by website or auth server.
Yes, I'm aware that this doesn't protect the api from numerous other vectors, but it does eliminate the simplest of cases which is all we're looking to achieve for now. I'll add, I didn't define this requirement, I'm simply trying to find a way to achieve it utilising techs out there instead of making the mistake of rolling anything of my own.
Could someone confirm/deny that there is an oauth flow I could use here? Any sample projects using the given flow and IdentityServer?
IdentityServer3 / non-aspnet[core/5] examples are fine, I can translate.
What you describe is the Client Credentials Grant where your website (client) gets an access token from identityserver (auth server). That access token can then be used to call endpoints on your web API (resource server).
The token is a bearer token and can be used by anyone who has it, so if you are comfortable with your website passing it back to a browser on an HTTP response, then it will work just fine.
I'm not sure what you mean by throttling the tokens - once minted they are valid for their lifetime. I guess you can keep the time-to-live very short to achieve the single usage you want though.

Resources