Same Domain SAML Request - javascript

I have some web application in my server which use ADFS for authentication let's say this is their URLs :
http://myServer/ManyWebApps/WebApp1
http://myServer/ManyWebApps/WebApp2
http://myServer/ManyWebApps/WebApp3
When the user access any URL under "ManyWebApps" hierarchy he can freely use the server function they provide through javascript and through the browser without further authentication:
http://myServer/ManyWebApps/Server/Function
Now, I need to detach one of my web apps to a new URL like so :
http://myServer/WebApp1
Will the user still be able to free access server functions under the "ManyWebApps" hierarchy :
access http://myServer/ManyWebApps/Server/Function from http://myServer/WebApp1
Note : both web applications are still on the same server and work with the same ADFS server, when the user enters http://myServer/WebApp1 he is authenticated, but will he be able to access functions on diffirent web apps on the server without further authentication?
P.S : I need to access a function without further authentication because making an AJAX request to the function while unauthenticated will cause the AJAX request to be redirected to the ADFS which it can't handle

CONFIRMED : The authentication is saved in http://myServer so no further authentication need to take place if both apps are on the same domain
When sending a request to the server, all of the user's cookies are sent including the authentication token. If the user's doesn't have the token in his cookies, the server will direct him to the ADFS. But since both web applications are under the same server, they share the same cookies which means once the user entered any address in MyServer hierarchy, he can free enter any in that hierarchy without further authentication

Related

How to know which user completed web/server side OAuth 2.0 flow initiated by a client such as a Chrome Extension?

I'm working on a Chrome Extension, and it's using personal access tokens (Laravel Sanctum) to authenticate the extension/user with the backend/server API. So basically when sending requests to the endpoints from the extension I'm including the Authorization header with the Bearer token.
I want to add some third party integrations which will use OAuth 2.0 for authentication, and I want those integrations to be connected with the user on the backend (server) and not the extension itself. Basically, my server (API) will be a proxy between the integration API and the extension.
In the extension, when a user tries to connect an integration, a window opens and my server redirects the user to appropriate integration authorization URL (with my client id, scope, redirect uri, etc.) where the user can then authorize my app. After that's done the user is redirected to the provided redirect_uri (my domain) with the authorization code.
What is a smart and secure way to know which user (my user, not integration's) connected the integration, considering that my user identification (including the token for communicating with my API) is stored locally on the extension, and is not immediately available in the OAuth flow.
My idea is, when opening the OAuth window, pass the user data to my server (GET or POST), store a cookie, and then redirect to the integration's authorization URL, and when the user authorizes my app and gets redirected to the redirect_uri, my user data will be available in the cookie so that I can assign the authorization code to the appropriate user. Is this a good way to do it?

Handle user session with access token + OAuth provider

I am building a web application with a basic client-server architecure. The frontend runs with react (nextjs) and the backend is on rails. However, the questions will be more about the flow of the authentication/authorization + session handling on the frontend.
I am using an Oauth provider to handle the authentication but don't need any authorization from their part as I don't need the resources of the oauth provider (ex. drive, calendar etc.)
For the authorization, as I want to access resources of my API, it's the API itself that handles authorization on any request made by the client (frontend) to the rails API.
Right now for the initial authentication this is the flow I'm using, Taken from https://blog.prototypr.io/how-to-build-google-login-into-a-react-app-and-node-express-api-821d049ee670 :
Implementation details important for the following questions :
I am using JWTs as access token (those generated by my API) and I simply sign them using a secret key that's only available on my API so the access token is unreadable from the front end point of view.
On the frontend, it is a react app and I used the following package to handle the OAuth flow google-react-login
Information received, what to use from Google (OAuth provider)
1- I receive(amongst other things) an IdToken and an access token from Google. Also I'm apparently supposed to receive a refresh token (which I didn't see). For my use case, all I need is the idToken from Google is that right?
Revoking of a refresh token (logout), flow for a re-login?
2- From my understanding access tokens need to be short lived for security reasons. So I need to return a refresh token to my client app to be able to generate new access tokens frequently. However, once a refresh token hits its expriy time, do I need to log out the user and prompt him to re-login through Google and basically redo steps 1 through 5 (Please refer to Figure 1)?
How to maintain the session through the access token
3- From the frontend perspective, can I assume that simply having a refresh token means the user is logged in? Once the server revoke the access token and the refresh token that means the user is logged out and I need to ouput a view of the web application for an unauthenticated user? That means after every page reload I need to check for the presence of an access and refresh token?
Thank you
I think you could improve your security and lower complexity by one thing - replace issuing of your own JWT tokes by a custom OAuth2 server. This OAuth2 server could use Google as an authentication provider. This way, your would not know about Google and it would just use your own OAuth2 server.
Then you can decide how to use it - whether the frontend will be the OAuth2 client or the backend.
If you choose the frontend, you will use the auth code flow with PKCE (as a public client). The fronend will use an access_token to authorize its requests to the backend. This way, the frontend will handle a session using hidden iframes. See the OpenID Connect Session Management RFC.
If you choose the backend, you will use the auth code flow (with a client secret). This way, your backend can maintain the session using a cookie (with secure, HTTP-only, SameSite options).
You can read the OAuth 2.0 for Browser-Based Apps RFC for the current best practices.

How could authentication work across microservices?

I have two separate Node.js services.
Service A is responsible for authenticating users. If a user successfully logs in, the user is redirected to Service B (hosted on a subdomain of the domain Service A is hosted on).
I am using JWT for authentication.
Question: How can Service B be aware if a user is or is not authenticated?
I imagine one way that Service B could be aware if they are or aren't authenticated is by asking Service A to check the JWT on each Request to Service B. But how is Service A supposed to send the JWT to the client when the client is going to be redirected to a new origin?
Is it safe to do something like:
window.location.href = 'https://b.example.com?jwt=tokenhere'
I don't believe storing the JWT on localStorage since it does not allow cross origin access.
Another bit of detail that the others haven't touched on:
If your clients are using web browsers, and if you want the user to be authenticated with both services without having to re-login (single sign-on)
E.g. if your domain is example.com, service A is at example.com and service B is at b.example.com.
Send login request to authentication service at example.com
Auth service verifies credentials and if they match, sends a cookie back to client with domain set to example.com
Client receives and stores cookie
On all future requests the browser will send the cookie to service A and service B
In service A and service B verify the JWT received in the cookie (see other peoples answers)
This method ONLY works when you're running on same root domain and your authentication service MUST be on the root domain. If you have a different setup I would recommend looking at a single sign-on product (e.g. Central Authentication Service)
Use RSA for your JWT generation. You can make the public key available to all other microservices. If the client uses CORS to talk to different services directly (vs. an API gateway), pack the JWT in the Authorization header as usual.
If your servers share a secret key you can encrypt and decrypt the token on any server. Inside the token you can write who the user is and what permissions he has. Whenever the user wants to perform some restricted action you decrypt the token and check wheter he has permission to do what he wants. Don't forget to give the token a time to live so it won't last forever.
I'm not a js guru so I won't paste code but you should be able to find an example here

OAuth2 flow in web frontend and REST API

I'm working on a project based on Phalcon which consists in two different stand-alone subprojects: a php + angular frontend and a php REST API.
I protected the API with OAuth2, using PhpLeague OAuth2 Server. The API server is the OAuth2's authorization server AND resource server.
This is the actual flow:
The user can browse the public endpoints of the frontend, and when hits a private page, gets redirected to the login page;
The login page has username and password, POSTs them to the frontend server;
The frontend server calls a public method on the API server, which is expecting a Password Credential Grant: it validates the credentials and sends back an access token and a refresh token;
The frontend server caches both the access and refresh token in session and uses it for some API calls: the first of those is the '/users/me', which gets info about the current user and its ACL on the frontend sections;
The frontend server sends the page to the browser, which loads its javascript files.
Now, OAuth2 states that access tokens should be short-lived and refresh-token should be long-lived: in the frontend server logic, the API calls which receives a 401 (caused by the expired access token) are retried by sending first the refresh token to obtain a new access token via a Refresh Token Grant. If this second call is rejected, I assume the user is no more logged in (refresh token expired / revoked).
The pages are using Angular to perform data and ux/ui management. My question is:
should the Angular code call directly the API server?
Actually the first thing my javascript code does is to get a config object from the frontend server, which contains the access token too, and uses it to make the calls to the API server. The problem with this is that i should rewrite again the "refresh token logic" in javascript (after it expires, i get 401s), and by what I have read on the subject i understood that it is better to not make the refresh token visible to the client (as it can generate new access tokens).
So i was thinking about a "two step approach", where every javascript API call goes to an endpoint on the frontend server which relays it to the API server, but this is obviously slower (JS -> FRONTEND -> API and API -> FRONTEND -> JS).
What is the correct approach? It's not very clear to me if the frontend should be considered as two clients (php + js) which should work separately or not, as I imagine that an hypothetical iOS app would be making calls 100% against the API server.
I have used the same approach in my own projects. The problem that we have is that the client is not secure. In order to generate / refresh a token, you need to pass secure information to the authorization server.
I have done the same as you basically, let the back-end handle the tokens and their temporary storage. You cannot and should not trust the client with important information which lets you generate tokens. In terms of delays, I wouldn't worry about it too much since you're not going to be doing that much extra work, you won't even notice the delays. I have a system like this built and used by hundreds of thousands of users with absolutely no issues.
Now, you have said a few things in here which make me wonder what you are doing.
OAuth2 is not a user authentication system, it's an application authentication system. You don't pass a user and their password and generate a token for them, you pass a ClientID and ClientSecret and they generate a token for you. Then you have an endpoint which gives you the user details for this user, you pass your userid or username and get the details of that user.
A token expired does not mean your user is logged out. Those are two completely different things. How are you going to expire a token for example, when your user wants to log out? You can't, your token will still be valid until it expires after the set amount of time has passed.
A token can be used for let's say half an hour, but your user may use the website for 1 hour. So before you hit any API endpoint, you could check ... has this token expired yet? if yes then you can go and refresh it and keep working without having to bother your user with a new login screen.
The whole point of an OAuth2 system is to make sure that only authorised clients can access it. A client is not a user, it's an application. You can have a website for example and you only want users of that website to access your API.
You can have endpoints like ValidateUser for example, where you take a username and a password and return a yes or no and then you log your user in based on that.
Irrespective of language/framework, second approach is secure and better than first one because to get access token by providing refresh token to Authorization server, it still requires Client ID and Secret which should never be passed to Browser for security reasons.
In first approach, to make a direct call it will not work if your Authz Server is hosted on different domain than your frontend server because of Same Origin policy of browsers. Even if they are on same domain, still you are exposing Client ID and Secret which will compromise your frontend server

OAuth request token for an installed application

I'm trying to use/understand Google request token mechanism. I intend to use it for an application I've start to develop to access Orkut data using OpenSocial API.
I read this document that explains the steps to obtain a token for an installed application. This document tells you to use the OAuthGetRequestToken method from Google OAuth API to acquire a request token . Accessing the manual of this function (available here). But the parameter oauth_consumer_key, which is required, asks for the "Domain identifying the third-party web application", but I don,t have a domain, it is an installed application.
So my question is, what should I put in this parameter in that case?
I'm using oauth_playground to run my tests.
Thx
From what i have read in the documentation, the following instruction on getting a request token implies that you simply pass 'anonymous' as the consumer key...
"1.The installed application contacts the Google Authorization service, asking for a request token for one or more Google service. The request is signed using the "anonymous" consumer key/secret." (OAuthForInstalledApps)
The trick is to create a hybrid auth process. You register a web app at a domain you own, authorize users for a web app via the OAuth for Web Apps process, then implement a mechanism by which their installed app can pick up that authorization from the web app.
My thinking on this would be that the installed app would send your site a request for a keypair. It would receive an initiate key and an authorize key, both of which you'd store in a database at the web site for one time use.
The app would then use whatever mechanism to launch an external browser, pointing it to
yourdomain.com/authorizestart.php?initiate=[initiate code]. The site stores the code in a session variable, then sends the user off to Google to authenticate. When authentication is successful and Google sends the user back with the next token, you store it in the database entry related to the initiate key.
The user closes the browser, clicks a "done" button in your app, and the app then sends a request to yourdomain.com/tokenretrieve.php?authorize=[authorize key]
Your site looks up the Google token and transmits it back, the app completes the Oauth process.
The issue with this is that you have to share the "consumer secret" you created in the registration process with the app. Someone could decompile it or try to capture its output and discover your secret key which is part of the method for encrypting responses from the Google servers. That said, how is that worse than using "anonymous" as your consumer secret?

Categories