Oauth2: Authenticate single page app without client secret when secret is required by service - vue.js

I would like to create an integration with quire.io, which currently only supports the Oauth2 authorization_code flow with client_secret.
This causes me a problem because my application will need a dashboard so users can configure it.
So far I have been trying to get a token on a backend server (which has the secret) and then send the token to the client in a cookie as a JWT.
Is there a way I can securely access the quire api from my frontend?

The authorization_code flow without client secret hasn't been implemented yet (different priorities).
For now you'll need the extra server to keep the client_secret in a secure place.

Related

ID token usage when using "Log in with Google" in a mobile app

Suppose that I have a mobile app with a frontend and a backend server.
My understanding is that -- when a user logs in the app with "Login with google", the frontend sends a request to the google auth server, and gets back an ID token. The documentation says that the frontend can then send the token to the backend server to establish a session. I imagine that means the token can be used in session-based authentication?
If I were to use token-based authentication (as opposed to session-based), do I just attach the ID token in every server request, and have the backend verifies it each time when processing a request? this page suggests the ID token should not be sent to the backend API. Which leaves me wonder what the correct procedure is for token-based authentication when using log in with Google.
So my question is: Does my server need to create an access token from the ID token from Google, and send it to the frontend, so the frontend can attach that access token in the API requests for authentication?
Thanks
Login with Google is an identity provider (IDP) operation. A full OAuth solution, including an authorization server (AS) looks like this:
Mobile app uses system browser to redirect to AS
AS returns a redirect response to the system browser, which routes to the IDP
User signs in at the IDP
IDP returns an authorization code to AS
AS swaps it for IDP tokens and carries out validations
AS issues a set of tokens to the app. This includes an access token (AT) with whatever scopes and claims are needed for business authorization to work.
Mobile app sends AT in API requests
API authorizes using scopes and claims from the access token
So ideally plug in an authorization server, to get this out-of-the-box behaviour. Another option is to implement your own token service, and issue your own tokens. That is less recommended though, since it requires more detailed understanding of the underlying security.

Cognito - Authorization Code Grant without secret key

I have a frontend app which I want to connect with a Cognito User Pool.
I am using openidconnect playground to test the authentication flow and this is my Cognito configuration:
I have not put a client secret because I don't think it is safe to have the client secret in the frontend URL.
This is the app client settings:
Using Authorization Code Grant due the rest needs a client secret.
So, this is the URL to do the login:
https://myuserpoolname.auth.eu-west-1.amazoncognito.com/oauth2/authorize?
client_id=YYYYYYYYY
&redirect_uri= https://openidconnect.net/callback
&scope=openid customscope/router customscope/modem
&response_type=code
&state=2282ed48ec2fc0eb0806a532f2eQQf02d0918949
After that, for the exchange to get the token I use this request:
POST https://myuserpoolname.auth.eu-west-1.amazoncognito.com/oauth2/token
grant_type=authorization_code
&client_id=YYYYYYYYY
&redirect_uri=https://openidconnect.net/callback
&code=bd105ab3-Z-X-Y-6109170d1e46
But if I don't share the client_secret as param it returns an error.
How can I do the authentication process without the client secret? Is that possible?
If not, how can I manage the client secret to avoid to manage it in the frontend application?
Thanks.
When using auth code grant type on public clients, you should use PKCE.

Generating an OAuth2 token from user logged in via Windows Credentials (Kerberos)

We are running an application via Remote Desktop Services. The application authenticates to our web api middleware running in under WCF using Negotiate and Windows Auth.
We now have a scenario where the middleware needs to make calls to another service and pass a bearer token so that it can run as the user who made the initial request. It would also enable us to not have to use Negotiate on every request, which is fairly expensive.
We're looking for a way that we can make a OAUTH grant_type = client_credentials, but using the credentials of the user which is authenticated via Negotiate to our middleware. I haven't seen any examples of how that would be done. All of the examples I see pass the users credentials via client_id and client_secret, or in the HTTP Basic Auth header, but no examples of grant_type = client_credentials, where the credentials are via Negotiate.
Getting a token as the user without the user interactively logging in via OAuth is generally not supported since the password is unknown.
Aim for option 1 below:
Use client credentials, then pass the user id in addition via a different parameter, such as a path segment - simplest option is to get the downstream service to support this
Login via OAuth and federate to an Identity Provider that uses windows auth - this is likely to be a very big migration job - though it is the preferred way to use OAuth with Windows auth

Client authentication in microservices using JWT and OpenID Connect

I've some questions regarding authentication in a microservices architecture. I've right now a monolithic application and my goal is to split the application in small microservices.
My bigest problem is for authentication (for now). After reading a LOT a documentation, It seems that the best solution is to use OpenID Connect to authenticate an user to retrieve a JWT that can by passed with the request to the microservices.
Also, to avoid having multiple endpoints, you can deploy and API Gateway to have only one endpoint for the end user. Ok, so now I've two questions with this architecture.
The standard flow for authentication will be :
An user contact my identity server in OpenID Connect with the implicit flow and get the id_token (JWT) and also the access_token. The user can now contact my API with this access_token. The API Gateway will valide the access_token with the identity server and also retrieve the JWT to add it to the sub request to the microservice API.
1/ How the API Gateway can get the JWT from the access_token? From what I red from the documentation (http://openid.net/specs/openid-connect-core-1_0.html), It can contact the "/userinfo" endpoint but It will get just the JSON format not the JWT...
2/ I want to allow authenticated calls between my microservices. So each microservice needs to be able to generate a JWT to contact other microservices directly. My first thought was to contact the identity server. But with the OAuth2 Client Credentials flow, I don't retrieve a id_token or a JWT. Just a classic OAuth2 access token without JWT. My second thought was that the microservice can directly sign its own JWT with a certificate issued by the same PKI as the one used by the identity server. That mean that a JWT can be sign by several certificats but from the same private PKI. When a microservice receives a JWT, It needs to be able to identify witch certificat was used to sign the JWT. I don't find anything on the RFC regarding this problem. I can add my own private claim in the token to have the certificate but after several days of browsing the web without seeing this kind of solution, I'm wondering if I'm not on the wrong path... To sum up, how can i perfom "User to service" authentication AND alors "service to service" authentication in JWT?
Thank you very much!
I am implementing a similar solution. Not sure if it will address to your question completely, but, I hope it helps:
You can implement a new authentication micro-service to convert your oAuth2 access token to JWT token. This microservice will also sign this JWT token.
Your API gateway will route all client requests to authentication service, which will validate this token from IDM and will convert it to a signed JWT token.
API gateway will pass this JWT token to other microservices which will validate the signature from Authentication Service's public key. If the signature validates, roles can be extracted out of it for authorization.
Each microservice can have its own IDM credentials configured and when it wants to call any other microservice, it can generate an access token and call Authentication Service to get JWT which can be passed in call to other microservices.

How to use oauth with 1st party client-side js app?

The model for our product is like this:
Api backend (headless)
I already have oauth set up and ready to use with a resource owner credentials grant. Anyone who wants to use our api can do so using either an API key or their username/password. Of course they also need their client ID and secret.
SPA frontend that accesses the Api
I have built an SPA that will uses the api to provide a portal GUI for our clients. Given that this client-side app is owned and administrated by us (so it's a trusted app) how can I safely authenticate users using only username/password with oauth?
Originally it was using a JWT auth system that only required username/pass but now that we've implemented oauth I'd like to consolidate. It's unreasonable to make every user need to also have their client id and secret on hand to login, but I want users to have full access to the api from the GUI.
I've looking at using CSRF tokens but how would that work with my app when nothing is generated server-side?
I'm not sure how to proceed.
EDIT: very similar to the problem here.
I have decided to use the solution described here.
And here is a snippet of my implementation
The TL;DR version is
Create a proxy between the app and the api
Store the client ID and secret in the proxy
App logs in using password grant type -- proxy intercepts login request and inserts client id and secret
On login response proxy returns access token as an encrypted cookie
Client stores cookie and sends with api requests (to proxy)
Proxy decrypts cookie and inserts access token into Authorization header before forwarding to api endpoint
For me this has several advantages over implementing something custom on the api itself:
No need for custom grant on oauth server
ID/secret is hidden from app securely and can still use password grant
oauth server can identify client (no need for separate client ids for each user)
You should not use the resource owner credential grant from a JavaScript application. The fact that you own and administer the application does not make it a trusted application.
A trusted client is an application that can keep a secret. SPAs or any JavaScript app cannot keep a secret.
You should use the implicit grant for non-trusted clients.