Does Passport utilize guards not to authenticate users but to validate access tokens on routes where these tokens are required? - laravel

I'm a little bit confused by the documentation. It's said:
Passport includes an authentication guard that will validate access
tokens on incoming requests. Once you have configured the api guard to
use the passport driver, you only need to specify the auth:api
middleware on any routes that require a valid access token.
So it means that Passport utilizes guards not to authenticate users but to validate access tokens on routes where these tokens are required. Did I get that right?

In this case, validating the access token is authenticating the user. To understand why this is the case, let's walk through a simplified authentication flow using JWTs (let's ignore oAuth2 for a bit).
The user is logging in on the website. This triggers a POST /login request, with the username and the password in the request body.
The backend validates the users credentials. If the credentials are valid, it will issue a JWT, which will act as an access token. The JWT payload will contain some data that allows the backend to identify a user, e. g. the user id. The JWT then is signed with a secret that only the backend knows.
The backend will return the access token to the client, who has to include the access token in any subsequent requests to the server. Usually, the client will provide the token in the Authorization header.
When handling the next request from the client, the backend will extract the access token from the Authorization header and check its signature. If the signature is valid, the backend can be sure that the token data has not been manipulated, e. g. by changing the user id on the access token. With a valid signature, the backend can extract the user id from the tokens payload and set the User model for that specific id as authenticated. With an invalid signature, the backend will probably return something like 401 Unauthorized.

Related

Configure Keycloak to include an at_hash claim in the id token

I'm currently using Keycloak 9.0.0. When authenticating using the code flow and exchanging this code, I'm receiving an id token without the at_hash claim.
How do I configure Keycloak to include an at_hash claim in the id token?
Background:
I'm using a "classic" server side rendered (SSR) program, a confidential client.
I'm sending requests to my local http api. But I also have an Angular client. The SSR is a Go programm using github.com/coreos/go-oidc.
Rendered pages that require authentication redirect the visitor to keycloak and back via the redirect_uri.
Since the visitor is logged in its id token is present in the session and I also pass the access token. However the id token has no at_hash claim and thus access token validation fails.
I also have a mobile web version of this site, in Angular and it sends a bearer access token once logged in. This app uses the code flow + pcke.
Both should be able to send authenticated requests, but since I'm using pretty much the only oidc client library for Go available, it requires an at_hash claim being present in the id token to be able to verify access tokens. The package currently has no support for the introspection endpoint.
Both id token and access token are returned from the IDP. But neither has an at_hash claim.
According to OIDC at_hash is mandatory only when access token is issued.
Make sure you are using response_type=id_token token and not response_type=id_token.

Understanding the authorization part of JWT and session

So i read about how authentication is done using JWT, where we basically verify if the token is valid using a private key (assuming RSA is the algortihm). And if the token is valid, then the user is considered authenticated. And I also read about session authentication where we check if the user supplied session id (through cookie), exist in the session store (assuming mysql / redis is used to store session). If it exist, then the user is considered authenticated.
But how do we use JWT and session for authorization ? Lets consider an action such as GET invoice , whereby a user can only view the invoice that he owns.
If we consider the user is already authenticated,
how do we check if the user is authorized if we are using JWT?
And how do we do it for session ?
You are probably confusing the things. One of the benefits using JWT is to avoid maintaining sessions which is big bottle neck in scaling.
JWT (Json Web Token) carry all the information that would require it to get authenticated, you don't need to maintain the session. Every single HTTP request to server will carry JWT that would contain necessary user claims including the signature. On server you will validate the signature to verify if the token is valid or not. You can verify the token without maintaining any session and there are number of ways to do it.
Since JWT is essentially a Json object (Header, Body , Signature) , you can put in claims (emails, roles, profile etc) in JWT body. Once you verify the token , you can extract the claims including any roles and check if user is authorized to access the resource.
You must look into Open ID Connect and Tokens here

AWS Cognito: Add custom claim/attribute to JWT access token

My app creates a custom attribute "userType" for each new signed-up user. Now I would like this "userType" claim/attribute to be added to the JWT access token whenever the user signs in or the token gets refreshed.
Is there an option to tell cognito to add my custom claim/attribute to the JWT access token? (Without a pre token generation Lambda)
Custom attributes are not available in Cognito access token. Currently it is not possible to inject additional claims in Access Token using Pre Token Generation Lambda Trigger as well. PreToken Generation Lambda Trigger allows you to customize identity token(Id Token) claims only.
You can use ID token to get the token with custom attributes.
Access tokens are not intended to carry information about the user. They simply allow access to certain defined server resources.
You can pass an ID Token around different components of your client, and these components can use the ID Token to confirm that the user is authenticated and also to retrieve information about them.
How to retrieve Id token using amazon cognito identity js
cognitoUser.authenticateUser(authenticationDetails,{
onSuccess: function(result) {
var accessToken = result.getIdToken().getJwtToken();
console.log('accessToken is: ' + accessToken);
},
onFailure: function(err) {
alert(err.message || JSON.stringify(err));
},
});
I have the same problem when I want to create several microservice. There isn't a way I can customize an access token, but only an identity token. However, I use client credentials in the machine-to-machine which needs access token. So, in no way I can customize my token. At last, I decide to add such info(like user type) in the event header. It's not a very secure way compared to customize a token, but there isn't any other easy way to do it right now. Otherwise, I have to rewrite the authorizer in Cognito. Like rewriting a customize authorizer and it's very painful.
I have the same issue with Cognito; exist other tools like "PingFederate"Auth-server of Ping identity and Auth0 Auth-server; I know that the requirement isn't part of the standard, but these applications were my alternatives to fix this issue
The responses suggesting to use the ID Token for authorization in your backend systems are bad security practice. ID Tokens are for determining that the user is in fact logged in and the identity of that user. This is something that should be performed in your frontend. Access Tokens on the other hand are for determining that a request (to your backend) is authorized. ID Tokens do not have the same security controls against spoofing that Access Tokens have (see this blog from Auth0: https://auth0.com/blog/id-token-access-token-what-is-the-difference/).
Instead, I recommend that your backend accept an Access Token as a Bearer token via the Authorization HTTP header. Your backend then calls the corresponding /userinfo endpoint (see: https://openid.net/specs/openid-connect-core-1_0.html#UserInfo) on the authorization server that issued the Access Token, passing such said Access Token to that endpoint. This endpoint will return all of the ID Token information and claims, which you can then use to make authorization decisions in your code.

Laravel API middleware - How to retrieve current user without requiring authentication

I have the following route in my routes/api.php
Route::get('/games/{game}', 'GamesController#show')->name('api.games.show');
On client side, I already included Authorization bearer token header in every AJAX request.
How can I retrieve the value of the user associated with the token throught $request->user() without having to require authentication (without having to use ->middleware('auth:api'))
Basically what I want is to have one route that serves for both authenticated (with token) and non authenticated (without token) requests.

JWT + Laravel Socialite with OAuth Parameters

What I want to achieve:
Safely allow users to connect their accounts to different social medias using a Single Page Application.
What I am doing:
I am using an SPA and therefor utilizing JWT as my user authentication method. I am passing the JWT token in the OAuth call with Laravel Socialite like this:
return Socialite::driver($provider)
->with(['provider' => $provider, 'token' => $token])
->redirectUrl($redirectUri)
->stateless()
->redirect();
On the callback I get the user based on the token. Using this method allows the third party provider to get access to the JWT token. Which is very unsafe.
My Question(s):
Is there any better way to do this? Should I use some kind of hash + salt + secret?
You should check the JWT.
JSON Web Tokens are an open, industry standard RFC 7519 method for
representing claims securely between two parties.
JWT Token composes of three parts, header, payload and verify signature.
You are using stateless authentication and the only way to authenticate the user is by the JWT Token. To authenticate the user after redirect, you should create a payload containing application's user id, and pass to the third party provider, so that when redirect, they will pass the JWT token back to you.
It is no problem to pass the JWT Token to third party provider, but be aware that the payload should not contain any sensitive data. If the payload is somehow sniffed, it will not have any harm because, if hacker is trying to change the payload, the verify signature helps and the application cannot verify the token and the application will throw exception.
The signature is used to verify that the sender of the JWT is who it
says it is and to ensure that the message wasn't changed along the
way.

Resources