Password Grant access token generation - laravel

I'm using Laravel Passport password grant type to enable my mobile clients(Android, iOS ...) to generate an access token. My mobile clients cannot use oauth/token route to get access and refresh tokens themselves, because it uses web middleware (as I understand). My questions is,
Should I make request to oauth/token myself in server by passing data mobile clients posted? If I do this how do I bypass web middleware. (Manually creating a dummy user and using it to bypass web middleware is not that I want and weird solution)

In my particular case I always this by removing \Illuminate\Session\Middleware\AuthenticateSession::class from the web middlewareGroup on app/Kernel.php.
I'm also using laravel-cors to allow Cross-Origin Resource Sharing headers. My apps are API only and the clients are external (both mobile and web clients are external) and they all authenticate and renew tokens themselves interacting with the Passport routes.

Related

Authenticate that a user has logged in with MSAL/Azure AD and serve them a token for my separate API?

I have an api written in GO that, at the moment, serves an authorization token based on a username and password. (Without MSAL)
I am trying to implement MSAL logins with Microsoft accounts. I have setup my angular frontend to log a user in to an Azure AD app registration. Would it be possible to authenticate that they have successfully logged in to the Azure AD, and serve them one of my tokens (unrelated to msal) from my GO API?
The username that they use to login with MSAL also exists in my backend, the flow would be something like this;
User logs in with MSAL -> my frontend makes a request to golang backend with username -> golang verifies that this username has logged in with MSAL -> backend serves a token for this user
It appears golang integration with MSAL is limited, so not sure how possible this is.
Thanks.
What you can do is acquire an access token for your API in the front-end from Azure AD. For this you will either register the API in Azure AD or use the same app registration. Either way, you should add a scope in the Expose an API page in the registration. Your front-end can then use that scope's id to get the needed token.
Your API can then have an endpoint that validates the access token, and issues the local token. The access token will contain the user's username for example, if you want to map to that. A more robust way would be to map to the user's object id (also in the token) since it is immutable, unlike the user email.
For token validation, you should be able to use a generic JWT validation library. Also remember to check for that scope in the token that you defined to properly authorize the request.

How to prevent exposing client secret when using laravel passport?

I'm trying to implement laravel's passport to protect my api routes and I have a case where the route should be inaccessible unless it is called by an authorized application. I am trying to use Client Credentials Grant Tokens and using postman I am able to generate an access token, which then I can use for access authorization.
The problem is - I don't understand how should I safely use this with Vue and axios. I have my component in which I need to call this api, I can of course set a form body including all the necessary fields (client_id, client_secret and grant_type) but that would mean that anyone could just open up chrome dev tools and search for client_secret in the source and they would get the hardcoded client secret, which would grant them access to the api. What is the right way to do this?
It depends on how you use your Vue frontend.
If it is a frontend mostly for your own site, but sometimes needs to access an external API, than you should have your backend make the API calls and store secrets there.
If you are developing a Vue frontend dedicated to the external API, but running on a different domain, you could go for the PKCE option: https://laravel.com/docs/8.x/passport#code-grant-pkce
If you have a frontend on the same domain as the API, use the CreateFreshApiToken option provided by Laravel passport.

Securing web app and api using OpenID Connect

I don't want to roll my own security anymore and am looking at using OpenID Connect with my c# API and AngularJS app. I can get all that to work just fine. However, my brain cannot seem to understand how to secure my API correctly for both use cases:
Use Case 1: AngularJS SPA
My AngularJS app connects to my API and sends a bearer token identifying the user and includes user claims. This one is easy and there is tons of documentation on it.
Use Case 2: API to API
Some customers want to access my API directly instead of going through my AngularJS app. In this case, I thought I could use a Client ID/Secret for toen-based authentication which is great except then I know nothing about the user that's using the client id/secret. There could be 10 users using the same custom API that is calling my API. How do I get user info via the API call? I've seen others use API keys that they then lookup the user and create a JWT but I thought there might be an easier way. Any ideas?
The whole point of API to API authentication is that there is no user context. Or well, the user in that case is the machine trying to access your API. You would then need to design your authorization logic around that and implement scope based permissions. Alternatively, your options are to use api keys as you mentioned or if you want OAuth protocol with user context in the api to api scenario - then ResourceOwnerCredentials flow is an option.
API to API communcation
You can use Client Credentials Grant defined through OAuth 2.0. This won't require you to have end user credentials. Now this won't be OpenID Connect. OpenID Connect require the involvement of an end user and bound to authentication. OAuth 2.0 on the other hand is about authorization, checking whether the entity can access the resource.
With Client Credential Grant, your identity server will issue tokens for a specific client. So one of your API becomes the client (resource consumer). From request handling API endpoint, you can accept valid tokens and respond back with resource.
If you require fine grained access control from request handling API, you will require to use token introspection to identify to whom this token was issued. In this case, it will be identification of specific client identity and execute a logic on top of it. You can check the token introspection response to identify such details.
Alternatively, access tokens can be come in form of a JWT. If this is the case, they can be considered as self contained tokens so validation is straightforward.

Laravel API Auth with Passport and React

I have a Laravel 5.5 Application that's using the session based auth out of the box. On some of these pages I have react components that need to get/post data from/to an API.
What is the best practice for handling this? Do I simply hide the API endpoints behind the auth? This would work but should I be using Laravel Passport for this instead?
I've had a play with Passport and it seems that this would work but I don't need users to be able to create clients and grant 3rd party applications permission etc. There is just the first party react app consuming the data from inside the laravel application (view).
From my initial experimenting with it, it seems I'd need to have the login call made first to receive an access token to then make further calls. As the user will already be authenticated in the session is there an easier way?
I'm not sure if Passport is intended to be used for this purpose or not. I'd rather take the time to get it right now as I'd like to get the foundations right now if the app scales.
You can proxy authentication with Passport. Using the password grant type users would still log in with their username/password, then behind the scenes make an internal request to Passport to obtain an access token.
Restrict what routes are available when registering in a service provider by passing in:
Passport::routes(function ($router) {
$router->forAccessTokens();
$router->forTransientTokens();
});
That limits access to personal tokens and refresh tokens only. A client will be created when you run php artisan passport:install.
Setup a middleware to merge the password grant client id and secret in with the request, then make a call to the authorization endpoint. Then it's just a matter of returning the encrypted token and observing the Authorization header for requests to your api.

SSO with Laravel Passport

I'm thinking to develop a full-fledged Identity System in Laravel 5 with Passport.
Following is my requirement:
I should have main identity management app like identity.mysite.com where all of my users are stored.
I have 2 other applications APP1, APP2.
When user request restricted resource on APP1, (s)he should get authenticated by identity.mysite.com
Once authenticated, let user access resources on APP1
Meantime, if user decided to access restricted resources on APP2, (s)he should not be asked to put credentials again.
Things I've tried:
simpleSAMLphp - SAML is an option which does these things for me. But it is not as mature as OneLogin and I'm not thinking to go in SaaS model at this stage unless it is necessity.
Laravel Passport - oAuth 2.0 seems tempting. I can even use, Passport Grant Tokens but I'm unsure on how reliable it is over SAML. Also, Laravel Passport is being widely used to authenticate API. Is it going to be useful while authenticating traditional session based apps? I haven't seen any example where the proper SSO is implemented with more than one application and laravel passport.
I know OAuth 2.0 is not an authentication protocol. Rather it uses something called Authorization but we probably can make it work to support Authentication protocol as mentioned here. Is it something, that Laravel passport supports?
This is what I call a resource oriented approach where all the clients(app1, app2...) want to know weather requesting user is authorized to access the resource or not...
Here we need to shift all the authenticating logic to oauth and make all our requesting apps dependent on OAuth. This way if user request app to access resources then if:
Token is present then app will request oauth server to validate given token and if found true then app will provide access to user.
If token is not present then you can solve it by asking for credential and app will transfer user data to oAuth server and validate it respond with the token.
As per my experience I use to implement this approach and I think Laravel Passport is an abstraction layer over top of your authenticating system. You can mold it however you need. There are few more enhancement and advancement can be done but this would work as a basic layer over top of your SSO.
You can achieve this with passport however you are right about the examples as there are not many or lacking on some steps.
You could to create a new middleware in App1 and App2 side that communicates with identity.mysite.com and gets the user data (token, scopes, etc, id) then it will verify if the token is valid.
On the passport server side you need an endpoint to return whether the token is valid or not and any additional info.
To avoid making too many requests to your passport server i would recommend to create a service that get the TTL of the access token and set it as the time on cache on App1 or App2 for the user data.

Resources