I m working on an application that needs SAML to manage authentication with an OpenAM server.
Actually, I use Satellizer with OAuth2 implicit grant flow and I have the following :
Open angularjs app in browser
Click on the third party login button
A new window hover the existing one (with ng app) is open asking me my credentials
I fill them, and validate
The pages made its stuff (generating token)
The angularjs application gets the token through the windows (how it is possible ?)
I can use my application with the OAuth2 bearer / jwt token.
I need to have something that works the same using SAML. The fact is that I m completely lost and it seems that I should log onto the SAML server using my backend...
I don't really like this situation and I need to know if there's something better to do using client side application.
What is the "usual" authentication flow with client side app with SAML ?
Thanks for your help
SAML2 was designed at a time when the concept of client side apps with JavaScript was not yet invented.
A common method is to use an intermediate OpenID Connect/SAML2 proxy/bridge (e.g. IdentityServer3 + Kentor.AuthServices.Owin) to authenticate users:
User starts log in sequence in JS app.
User is redirected (part of OpenID Connect flow) to IdentityServer3.
User is redirected (part of SAML2P) to SAML2 Idp.
User authenticates at SAML2 Idp.
User is redirected back to IdentityServer3 (part of SAML2P).
User is redirected back to JS app (part of OpenID Connect flow).
This works excellent to get the user authenticated with an external Idp. If you have resources, such as backend services, those calls are usually authorized through an OAuth2 bearer token issued at step 6.
If your backend API is expecting a SAML assertion instead of a bearer token you will have to look at our ways though.
Related
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.
I'll put them in context first.
I am developing a Rest API using laravel and as an oauth2 authorization method using Laravel Passport as an implementation.
On the other hand I am developing a Javascript client (Single Page Application or SPA) that will consume the API Rest.
The situation is as follows:
Some API Rest endpoints must always be accessible by the client (a valid client since the API is not public) and other endpoints must only be accessible by the client when a user is logged in.
In a first approach what has been proposed is that when the SPA is initially opened in the browser, you get a Client Credential Grant Token so that it is a valid client and can make requests to the "Basic" endpoints of the API. Later, when a user logs in, a Personal Access Token will be generated which will allow the client to make requests to all endpoints of the API Rest.
I'm a little confused as to how to put this into practice.
I hope, please, you can help me.
I have some questions for the following flow involving OAuth2:
webapp1.xyz.com is a registered client with authorization code grant type, here's the current flow:
User logged in and redirected with authorization code to webapp1.xyz.com
webapp1.xyz.com exchange authorization code for access token and store it to session
webapp1.xyz.com server side needs to make calls to webapp2.xyz.com api by passing on access token
webapp1.xyz.com has SPA where ajax calls webapp1.xyz.com api end point (passing on session cookies in request)
User logged out, session is destroyed
There is a suggestion from someone to make the ajax call using (implicit grant) access token instead of session cookies. Is that even possible mixing authorization code and implicit grant type? Maybe I am mixing something, I cannot see any reason why using implicit grant type for the ajax part.
Is that even possible mixing authorization code and implicit grant
type?
The problem is more that you talking about one token for two applications. Or rather, webapp1 is both an OAuth client (web site which calls a web API - webapi2) and an OAuth resource (a web API which the SPA can call using implicit grant).
So: SPA javascript > webapp1.xyz.com application > webapp2.xyz.com application.
In Oauth2.0 terms your SPA client app would be a client, and webapp1 and webapp2 would be resources. the client would ideally use the implicit grant to get an access token as that's the optimised flow for a public, javascript client.
If possible, maybe look at a hybrid flow - OAuth2 and OpenID Connect - instead of the authorisation code flow.
Using the hybrid flow, webapp1 will get a token as currently, but it will also get an ID token which it can pass back to the SPA.
The ID token is intended for use by a client for authentication purposes - this ID token could do the same job the session cookie was doing (i.e. authentication between SPA and SPA backend). And the access token would be stored safely on the webapp1 server away from the SPA.
I'm struggling with implementing a proper front-end auth solution for my de-coupled setup. It consists of the following:
Server-side Ruby API (using Warden for email/password auth)
Client-side Backbone.js app
I think I'm stuck at how to properly pass tokens from the server to the client.
This passage from staticapps.org explains the type of flow I'm looking to achieve:
The client directs the user to a server-side authentication process. This may be a JavaScript pop-up window or a browser redirect triggered by setting window.location.
The server authenticates the identity of the user via password, social sign-in, or other means.
The server creates a randomly generated token and associates it with the now authenticated user.
The server transmits the token back to the client.
The client includes the provided token on subsequent requests to the server as a proof of identity, granting the user access to protected resources.
Any ideas how to achieve this with Warden on the server?
Note
I should mention that I'm leveraging Rack::Session::Cookie which I assume will be the unique token that is passed back and forth?
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?