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

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.

Related

When an Oauth provider is used to delegate authentication, then does the appserver return any token to the caller?

In Oauth and Openidconnect, the appserver endpoint invocation starts the Oauth flow and the app server gets the token from the auth server and is able to pass the token to resource server to access resources (delegation) on behalf of the resource owner.
The token exchange happens between the app server and resource server, and the token never arrives at the end users browser.
I'm working on a web api (aka app server) that will be consumed by a mobile app. There is no other server involved. Presently the login endpoint returns a signed JWT token to the user if correct credentials are supplied (validate against the db). User places this token in the header of the subsequent request.
Assuming I don't want to have a user db and validate logins, and instead delegate the auth check to another service like azure b2c or firebase (that use the Oauth), then I assume the flow is like given below:
Api registered the firebase/azure b2c (let's call this the provier) clientid, secret.
User invokes login endpoint of my api
The api invokes the provider's Oauth flow.
User gets popup to authenticate with the provider.
Eventually the provider will send the token (containing the claim like username) to the api (aka app server)
Does the user get back any token? Otherwise, when the user makes subsequent endpoint calls, then how is the endpoint able to identify who is this user and whether he is already authenticated?
Although it is okay to send back the access token to the user , but from the security best practise 's point of view , it is better not to do it which I quote the reasons as follow from this:
Because of the issues outlined above, the best security recommendation
for an SPA is to avoid keeping tokens in the browser at all. This can
be achieved with the help of a lightweight back-end component, often
described as a Backend-For-Frontend.
The backend component can then be configured as a confidential OAuth
client and used to keep tokens away from the browser. It can either be
stateful and keep tokens in custom storage, or stateless and store the
tokens in encrypted HTTP-only, same-site cookies. Whichever variant is
chosen, the backend component creates a session for the SPA, using
HTTP-only, secure, same-site cookies, thus enabling a high level of
security. Such cookies cannot be read by scripts and are limited to
the domain of the SPA. When combined with strict Content Security
Policy headers, such architecture can provide a robust protection
against stealing tokens
Also from here ,they suggest for mobile app 's OAuth2 best practise , it should perform the OAuth flow inside a system browser component.

In token-based authentication, who should create the JWT, the app developer or the auth server?

I have a general question on token-based authentication. I've seen multiple guides that seem to say conflicting things, so I'm confused:
Question
Who should be responsible for creating the JWT, the app developer (via the app's backend server) or the auth server (ex. the Identity Provider)?
(1) Here [0], it explains that the developer needs to generate + hash the JWT and use that as the bearer token for any request. From there, the auth server can use the shared secret key to validate the token.
(2) Here [1], it says the auth server generates the JWT and returns it to the client once the login is provided + validated (no backend server involved on the developer's side).
Which one is correct? If they're both correct, how do I know which one to use?
My understanding:
(1) #1 above is one where the developer stores the secret in the backend server of their app. The backen serves as the middle man between the client and the auth server to make authenticated requests without exposing the secret + access token.
(2) #2 above is one where the app has no backend server at all (SPAs like Angular/React). The client interacts with the auth server directly (aka no secrets involved). Per [1], the IdP only uses the client ID, scope and few other things to generate a JWT.
[0] https://enable.cx.sap.com/media/1_uup99qpg (skip to 1:49)
[1] https://auth0.com/blog/handling-authentication-in-react-with-context-and-hooks/ (scroll down to the first block of code under "Add authentication to your app", where the Auth0 instance is configured)
Depending on the project requirements/budget/timeline, the JWT can be created by the developer, or it can be managed by a third party (e.g. Auth0).
Terms
Authentication Server
Receives user credentials (e.g. username & password)
Validates user credentials (e.g. compare username's stored hashed password in the database to the result of hashing the password from the request)
If token is valid, server responds with a token that is used to authenticate future requests (often automatically stored in a cookie in the client by passing it in the proper header in the auth server's response, which can then be automatically included with every request).
Can be written from scratch (allowing for more customization), or can be handled by tools such as Auth0
Scenario 1 (SAP)
This scenario involves making authenticated requests to a third party API.
Your frontend accepts user credentials
Your backend ("authentication server") validates credentials
Your backend responds with a JWT token, created using the RSA Key from SAP, your User ID from SAP, and likely the User ID from your backend server so that you can ensure that the user making a request to authorized to access the data requested. NOTE: Auth0 can be used to create the token, if it supports storing and passing custom values to the JWT
Your frontend makes a request to your backend, including the JWT
Your backend ensures authorization (Auth0 can be used if it supports creating custom logic for checking authorization), then makes the relevant request (based on the request from the frontend) to the SAP server and passes both the JWT and the API Key (stored on your server) with the request
SAP verifies the JWT, and responds to your backend with the requested data
Your backend then passes the relevant data to your frontend
Scenario 2 (Auth0) - YouTube Demo
This scenario uses a third party auth server to authenticate/authorize routes on both your frontend and backend (both of which will leverage Auth0 tooling).
Your frontend directs the user to Auth0's login page
Auth0 redirects back to your frontend, where it stores the JWT
When a user clicks on a button on your frontend that takes them to a different route (e.g. /profile), your frontend can use Auth0 to see if they are authenticated/authorized and extract relevant user data.
When a user clicks on a button on your frontend that makes an API request to your backend, it sends the JWT token with the request, which your backend uses for authenticates using Auth0, and then responds with the relevant data (if the user is authorized to receive it).

OpenID Connect Hybrid flow for authentication only

I have a mobile app and I want to use OpenId Connect to authenticate users against an external auth provider. I only need the id_token to get the users' email address, I don't need an access token (at least for now).
Are there any vulnerabilities of using a hybrid flow where I do the first request on the front channel and I set response type = code id_token?
If/when I'm going to use an access token, I plan to send the code to a backend to do the exchange for an access token. I'm just not sure if there are any vulnerabilities to retrieving the id_token on the front channel.
The standard flow for mobile apps should be to redirect with response_type=code as in step 8 of my write up.
You then get only an authorization code and perform an authorization code grant message to get tokens. Whether you get an access token should be configurable in the Client entry in the Authorization Server.
You should use PKCE parameters so that no-one can get tokens if they happen to intercept the authorization code.
In the event that you can't prevent an access token from being returned you can just discard it from memory.

Access tokens in auth0

In auth0, a user authenticates themselves with auth0, then sends an access token to the app so that the app can make API calls. My question is: when the user authenticates themselves with auth0, what does auth0 send back to them? Is it an access token? If so, how does it differ from the access token that the user then sends to the app?
Thanks!
It gives them a token that you must verify with auth0 servers to make sure it's valid.
Auth0 sends back a few different types of tokens to the user.
The main ones are ID Token and Access token (as you have already mentioned).
Consider the following example assuming the setup of a web application & an API.
The user signs in to Auth0 through the web application and gets back the tokens mentioned above. The web application can then store the access token (for example in local storage) and attach this to requests to the API.
The API will see this token and can verify it has been issued by Auth0 and that the user has sent a valid access token. Then the API can know that the user is valid and can respond with privileged info.
To directly answer your question, the access token that the user gets back from Auth0 is the same one that it sends to the API. This will be sent around in jwt form which can be decoded when needed.

How to get a JWT?

When reading about securing an app with JWTs, it is often said that the client initially gets a token from the server and then sends this token along with every request to the API.
This approach works great, once you have a token. As far as I can see, the default way of transferring a token is using an HTTP header, namely Authentication with Bearer as the prefix of the token as value.
But - is there also a default way of how to get the token initially? In samples you often see that this is just a simple request to and HTTP endpoint, that then returns JSON. But I was wondering whether there is something more of a standard workflow that e.g. describes what should be the name of this endpoint, as in OAuth2?
Any hints?
JWT is a token format which is used in security protocols like OAuth2 and OpenID Connect.
How to get the token from the authorization server depends on the grant flow you are using.
There are 4 grant flows defined in OAuth 2.0 that are intended for different clients and uses.
Authorization code grant
This grant is intended for web applications. The user's browser is redirected (HTTP 302) to the authorization server. The authorization server takes care of authenticating the user (via username/password, smartcard, 2-factor auth whatever).
The authorization server then redirect the browser back to a preregistered endpoint in the web application with a code. The web application then uses it's own credentials (client id and client secret) and the authorization code to request an access token from the authorization server.
The authorization server returns an access token and a refresh token to the web application. Note that the browser (untrusted) never sees the access token. Only the web application (trusted) has access to the access token and refresh token.
This grant is difficult to use from other clients than web applications as it's based on HTTP redirection.
Implicit grant
This grant is used for untrusted clients like JavaScript applications or 3rd party mobile clients (the ones you download from the app-store).
It also redirects a browser (or browser control) to the authorization server, but instead of returning a code to the browser after successful authentication, it returns an access token directly. Because the client is not trusted, the grant does not return a refresh token. The access token needs to be stored somewhere and is vulnerable to XSS attacks.
Even though you do not get a refresh token, some implementations do provide a way to get a new access token by communicating to the authorization server in a hidden IFRAME and using cookies to authenticate with the authorization server itself.
Resource Owner Password Credentials grant
This grant is for trusted clients, for example a desktop application or a first party mobile app with secure storage capabilities. The client application asks the user (the resource owner) for their username/password and then sends this to the authorization server to acquire an access token and refresh token.
Once the client has the access token, it can discard the password as it can use the refresh tokens to get new access tokens. This makes it more secure than basic authentication.
This grant does not depend on browser redirects and can be easily used from any application that can execute HTTP requests.
Client Credentials grant
This grant is meant to authenticate the client (application) instead of the user of the client.
In this case, the client submits its client id and secret directly to the authorization server to acquire an access and refresh token.
So basically the first two grants depend on browser-like capabilities (HTTP redirects, HTML login pages), where the other two grants only need an HTTP stack to communicate with the authorization server.
Every OAuth2 server has its own endpoints. The client can discover the name of relevant endpoints using discovery protocols like http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata.