OAuth2 Implicit Grant wihtout resource owner authorisation - security

This is something driving me crazy since last 48 hours.
The idea is to have implicit grant for SPA application with auth server (managed by us). I can see the flow where user have to login using our own identity database or via google (for e.g.) which is fine.
but there are other scenarios where Auth server only want to make sure the request have come from a valid (registered client). For e.g. in the Application (Resource)'s new User Registration function or Forget password function. Obviously under this scenario User will not be logged in as he/she does not have username/password in first place.
Under this circumstances how do we use implicit grant just to make sure the request is coming from a valid client and not some hacker's site?
Is this even possible through implicit grant?
Thanks

With implicit flow the client should be registered with a client ID and callback URL.

Related

Getting OIDC username after authorization

My goal is to tell if a user is authenticated, and get their name and email. So far, I can only do the first.
My server app is a NodeJS/Express router. The OIDC server is provided by my company, I believe is compliant, but not under my control. I can do an "Authorization code flow": response_type="code". My Node app eventually responds to the callback route and I can get the "code" and "grant_id" query string values. Other than knowing they exist and presuming that means the user is authorized, I have no idea what I can do with those values. It appears that the only scope that works is "openid".
If I can get the access_code, I can call the UserInfo service and get these values.
My other choice is to do an implicit call. Unfortuantely, the OIDC service it provides the "access_code" and other values after a hash mark on the callback. I believe the flow to be like this:
User makes call to Node app. Detects a lack of authentication, issues redirect to SSO service implicit authorization
User's browser follows redirect to SSO service implicit authorization. User fills it out and is successfully authenticated.
W3 returns a redirect to the provided callback URL.
User needs to cooperate with the app, somehow parse the query string parameters to get the access token and pass this back to the Node application.
The browser calls the provided Node callback application, but without the necessary access token.
I think I could make a proxy server to force OIDC to give my node server the request, just so I can get the access_token. It seems like a very convoluted way to do this, so I have to think there's some simpler way.
Again, all I want is to know the user is authorized to use the app, and what their name and email is. It should not be this hard.
You can use the ID-token to get the details about the user.
It is also important that your identity provider is all about authentication. Final authorization checks should be done in the client, by examining the scopes/claims in the token.

OAuth 2 Implicit grant type for first party SPA - Most secure and sensible way

My aim is to secure my stateless API and only allow the registered first party clients (SPA) to consume my resources. There is not going to be any third party clients in my scenario.
I know Oauth 2 authorization with implicit grant type is recommended for public clients (in my situation, a SPA). I have read lots of things about that but i couldn't understand some points, so i'm asking for your help:
1- Do you think Oauth 2 with implicit grant type is the best way to accomplish this? I know password credentials grant type is not safe for SPAs, because they can not maintain the confidentiality of a client secret. So should i go with Oauth 2 with implicit grant type?
2- In Oauth 2, i can use the implicit grant type with auto approval, so taking the consent of users are not necessary anymore. But as i think of my SPA as a first party app, i don't want any users to redirect anywhere to login and get back to SPA page.
Do you think it is secure and sensible to enable http basic authentication for my API, so then my first party app would be able to get user credentials and add it to authorization header and sent to my Authorization server over SSL/TLS channel to authenticate and get access token?
If it is not appropriate, what do you recommend to achive this goal?
3- I want also unauthenticated users to consume some resources in my SPA; should i make those resources public for any client and any user (actually i don't prefer) or expect SPA to authenticate and authorize withe a dummy anonymous user to get an access token with anonymous privileges to consume public API resources.
4- For a Wikipedia like website, how long should it take an access token to expire?
5- When it is expired, what method should i follow? There is no refresh token in Oauth 2 implicit grant type. Should i ask users to enter their credentials again (this is not user friendly) or store their credentials in a storage and sent it to authorization server silently to get a new access token?
Thank you for your help.

Which OAuth2 authentication flow shoud I use for PWA + server side application

I am trying to choose the right authentication flow for an application:
Fontend is an Progressive Web App accessible only via HTTPS. It'is done in Angular, Single Page Application.
External Authorization Server
Backend accessible via REST calls
For now I am using Authorization Code Grant flow.
What have I tried:
I've checked official site. There is a list of possible flows (Authorization Code, Implicit, Password, Client Credentials, Device Code, ...),
but no clear indication how to choose between them.
Then I found this excellent article on Auth0.com. Unfortunately PWA + server side beckend is not present in their scheme.
Could you please tell me what OAuth2 flow is appropriate to my context and why?
Assumptions (the way I understood the question):
You own and develop both frontend (Angular app) and backend (server-side REST API).
You want to outsource authentication to a 3rd party identity provider.
You want the Angular app (Client) to hold the token and be able to authenticate on the backend (Resource Server), with the identity of your user (Resource Owner) established on the 3rd party (Authorisation Server / Identity Provider (IdP) ).
First, a sidetrack. For this use-case, OpenId Connect (OIDC) would be a better fit, because that supports the identity element. The point in OAuth2 is to authorize your app to do stuff on the 3rd party. What you want is establish the identity of your user, with the help of the 3rd party, and that's what OpenId Connect does.
Ok, so which flow (OIDC is still based on OAuth2).
The first questions are whether the Client is trusted to do anything on the Resource Server, and whether it can securely store a secret. This is clearly not the case, a client-side app is not trusted, and cannot hold a secret. In the client credentials flow, the client uses a secret to authenticate on the IdP to receive a token for the resource server. This would mean your Angular app stores a password which it uses to get a token for your backend, clearly not what you want.
Resource owner password credentials flow is used when the client is trusted to handle user credentials. In your use-case this is not good, because practically it would mean your Angular app would get the users password to forward it to the IdP in exchange for a token. Your Client should not have access to the user password, it is not trusted.
Now comes the more interesting part.
The question is whether your Client has a server-side to securely hold a secret. If it does, Authorization Code Grant is good, because it allows your user to authenticate on the IdP, get redirected back with an authorization code, and the server-side can then exchange that for an access token to be used on the resource server. However, your Client in this scenario does not have a server-side, as far as I can understand the API is the resource server. So this is not good for you, because it needs a client secret, and you can't store it in your Angular app.
And this pretty much leaves you with the Implicit Flow, for which you don't need a client secret, but on the other hand it's difficult to do things like refresh tokens. In the flowchart you linked to, the last question is whether your Client is an SPA - and in your case it is, so you should go for the implicit flow by default.
This is probably the most secure model for you, because even in case of a compromise of your Client, your user credentials are still safe (the Angular app never has access).
However, you can model this whole thing differently, and that simplifies it quite a bit.
As far as I could understand, you own both the Client and the Resource Server, and the Resource Owner is using the Client, you just want to offload authentication while you still manage users in a 3rd party service.
Looking at it this way, your Client is trusted to access user credentials, and the user using it is the Resource Owner. So you could use the Resource Owner Password Flow, where the user enters his credentials directly into the Angular app, which goes to the IdP, gets a token, and Angular simply uses that to access stuff on the API (Resource Server).
The risk compared to the Implicit Flow is that if the Angular app is compromised, user credentials will be disclosed to the attacker. Whether you want to accept this risk entirely depends on you. Note that this would obviously not work if the IdP is a well-known service (like a social website for example), because as your user I wouldn't want to give my social site password to your app. But as long as you manage users anyway, it can be acceptable to trust the Client.
While the previous anwser was perfectly accepted in 2018, it should be considerate as a security risk nowaday.
IETF source concerning implicit flow.
The correct flow to used now for a PWA and in general any public, browser based client that can not rely on client_secret is the authorization code flow + PKCE

SPA + API OAuth flow, what to use?

We are struggling about what OAuth flow to use with our app.
We are using Node.JS as our back-end API and Angular as our front-end.
What we want to do is, log in an user, retrieve an access token and use this access token in order to make some API requests (basic POST/GET/PUT/DELETE).
A user (still unknown at this point) lands on a login form OR a register form. He proceeds to the login or the registration.
Once logged he's on his dashboard with an access token, now every time he wants to interact with the API he must use his access token in order to interoperate with the back-end. (which is a classical behavior).
This seems easy, we wanted to use the Implicit Flow but we need a client_id in order to retrieve an access token and the user is still unknown at this point.
We then thought about using the Password Grant flow because our users will have a login/password, but OAuth specs. recommend not to use it except we have no choice.
I know this is a super basic question but what kind of OAuth flow do you recommend with this ? If we have no choice we'll just use the Password Grant but wanted to explore every single solution.
Thanks !
I'm not sure I understand what you mean by:
we wanted to use the Implicit Flow but we need a
client_id in order to retrieve an access token and the user is still
unknown at this point.
If you are using Oauth2.0s implicit flow then your angular app should be registered as a public client with the authorisation server - that process would give you a unique client_id for your angular app. Your angular app can then use the implicit grant and redirect the unknown user to the authorisation server's authorise endpoint passing along in the querystring its client_id along with its redirect_uri and various other things.
The authorise endpoint will prompt the user to register/login to the identity provider and consent to the scopes your Angular app requests.
Once the user logs in (or registers), the authorisation server should then redirect back to your Angular app's registered redirect_uri passing an access_token in the hash-segment of the returned http querystring.
Sorry, I know that I'm not answering directly to your question.
But did you consider using an authentification backend as Auth0 ?
Security is key and OAuth is a complex protocol.
Auth0 give you every thing you need to manage users, use a social identity provider, and integration with Angular.

Building a Web-API with Oauth2/OpenID connect

I'm trying to understand conceptually and practically how to perform an oauth2 with openID-connect flow in my web-api application, utilising Azure AD.
Importantly, when a request is made to the API I want to know who made the request.
My current understanding is :-
My client would detect that the user isn't logged in and redirect to a sign-in.
The user would provide their credentials, and be redirected back to the client, along with an oauth2 token.
This token would be supplied to web-api endpoints for any requests.
This is where it gets murky for me.
How exactly do I use this token to authorize access to a particular resource, determine who is accessing the resource, and what is the mechanism that does so?
I'm sort of assuming that I would need to reuse the token to make a call to the Azure AD user endpoint - if the token was indeed valid, the AD endpoint would return the users details - thereby providing some means of determining that the token is valid and providing details on the users identity. Authorizing access to a resource could be done through membership of groups in Azure AD.
BUT ...
I can only assume this a solved problem, and have noticed use of OWIN middleware as per this example
https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet
But I'm still rather unsure as to what is exactly going on.
The service makes mention of scopes and claims, but I don't understand where these are derived from (I assume from a token supplied by the client, but not sure). The service must be receiving identity information in the call.
Which brings me to two points, for this to be secure -
The token provided in call to the service would need to be secured in transmission (hence the use of HTTPS) - to prevent MITM.
The token would need to be signed some how - I guess by using client secret or something - to prevent information in the token being spoofed.
Can someone help me clear up this muddled mess?
In particular -
How is the identity of the API caller determined - is identity determined from a call in the client or the server?
How to limit access to some endpoints of the API based on a user role?
What do I do to practically achieve this by building on existing middleware and libraries available to me?
Disclaimer: This will not be a comprehensive answer. It is off the top of my head.
OpenID Connect provides an identity layer on top of OAuth. In your case, Active Directory provides the authentication and sends back an access_token. The access token represents a user that AD has authenticated. If your doing OpenID Connect, then AD will also send an id_token, which may contain additional identity information (such as birthday, avatar, and whatever else AD exposes.)
Neither OpenID Connect nor Active Directory have anything to do with the the roles that your app assigns to a user; roles are entirely the bailiwick of your app. You assign user roles just like you normally would; you assign them to the nameid though instead of to an email address or username. Your app no longer has to authenticate the user but it does need to assign roles to the nameid.
How is the identity of the API caller determined - is identity determined from a call in the client or the server?
The identity is embedded in the access_token that AD includes in its response. This token will have a nameid in it that your app can associate with a user and role. The nameid is like an email address, username, or other uniqueID that your app uses to recognize the user.
How to limit access to some endpoints of the API based on a user role?
You choose. When your app receives a request with a particular access_token, that token will be associated with a particular user via its nameid, and you can assign whatever roles and rights to that user. Basically, associate roles with a nameid.
What do I do to practically achieve this by building on existing middleware and libraries available to me?
There is an unfinished demo here, though it doesn't use Active Directory as the provider, instead, it uses an internal provider. For the demo, the username is shaun and password is Testing123!. The source code is here.
Here is the link to the source of another demo, though again, it doesn't use Active Directory as the provider, instead, it uses Twitter.
The nice thing about OAuth and OpenID Connect is that we can use whatever identity provider we want, so you can adapt the demos to use Active Directory.
Apart from question #1 (the identity is verified on the service side) all your question are very open ended and would require a super long answer.
I would recommend reading https://azure.microsoft.com/en-us/documentation/articles/active-directory-authentication-scenarios/ - it is a good introduction to the flows underlying many of the modern authentication cenarios, including the web API one you are focusing on.
Once you have read that, you will find a complete set of samples in https://azure.microsoft.com/en-us/documentation/articles/active-directory-code-samples/ - in particular, I suggest studying the web API and thru authorization one to find guidance on the 3 questions you listed. HTH!

Resources