I'm having I think, a misunderstanding of concepts related with Oauth2 protocol. Right now I have 3 applications:
Frontend developed in React
OAuth2 server developed in Golang (not finished)
Another backend app, let's call it: Bussiness Logic app
At first, the user from react can login in the system using the OAuth2 server, the OAuth2 server sends the token and everything's perfect.
Now, when from the the react app some request is send to the Bussiness Logic App the token is also send in the headers. My question is: having the token, should I be able from the Bussiness Logic App to get information fo the user making a request to the OAuth server? is it allowed in the OAuth protocol?
The thing is that I need to know in the Bussiness Logic App which user is logged in, if it's not allowed, how should I fix it?
No.
OAuth 2.0 NOT an Authentication protocol.
If you need Identity Information you need to use OpenID Connect (which is built on OAuth 2.0)
With OpenID Connect you are provided both an Access Token and an Identity Token. The Identity Token will contain "basic" profile information about the "user". The Access Token may be used to obtain more detailed information about the user from the userinfo_endpoint.
Related
I have a web app developed using Create-react-app
I host it on IIS, the IIS only response to load the app, there is no server side logic on it (no Express or any other web server)
The app is using a RESTful API on the same IIS, it is out of my control (I cannot make change).
Now one of my client request to add SAML SSO to our app.
I would like to know:
in normal situation, which one is the Service Provider? My IIS Web server? or the API service?
For my case, I cannot implement SAML to API service, my web service only used to load my app without server side logic, how can I implement SAML?
Could any one give me some React implement SAML SSO tutorial or article for reference?
Thanks for any help, any information or suggestion are welcome!
in normal situation, which one is the Service Provider? My IIS Web server? or the API service?
I assume the client wants to authenticate the users using their internal IdP. So your application is the SP. But you will have to define different token service (details below).
With SPA (a single-page-applications) I see the problem, in SAML the user is redirected or posted away from the SAML request and SAML response.
I have a login page to enter id/pw, post them to API server Login endpoint to authenticate and get back a JWT token. After that we use that token in API calls for authentication
The API services are using a JWT token issued based on the provided username/password. I'd recommend to extend the token service (or use a different service) to issue a JWT token based on the provided SAML response - a token swap service. In many OAuth implementations it's called SAML grant type.
I cannot implement SAML to API service, my web service only used to load my app without server side logic, how can I implement SAML?
Usually after the authentication the user is redirected or posted to the SAML ACS endpoint URL, where the server can create sort of session (cookie, parameters, token, ..) and the user is redirected to a URL returned the web page with the session information.
If you are using an SPA, you could use a popup window or SAML with redirect (not with post), where the page could read the SAML response parameters (assertion, signature, ..) and use them in the token swap service mentioned above.
When processing the SAML response, try to use some mature, known, out-of-box libraries, it's a security service and not doing it properly may cause security weaknesses. But you need to do that on the server side, as at the end you need the JWT token consumed by the APIs.
We want develop few different services (React Apps) with the same users database and Rest API.
Some users might have access to APP 1, some for APP 2, some for both depends on their role.
We decided to go on multiple subdomain apps method.
We want SSO so only one page/app to authenticate all the apps and not a local login component for each app. using JWT mechanism in our backend.
STRUCTURE:
AUTH FLOW:
There are two main problems in this flow which are marked as 1 and 2:
Lets say i go to the login app and log in, getting accestoken from the backend.
How do i deliver the token to app1.company.com? should react login APP redirect with token in url param?
local storage is subdomain scoped.
iframe has problems with Safari.
I don't wanna save jwt in cookies for now because the flask REST can serve non-browser retailed clients.
Lets say the user want to go to app2. if we aren't able to share the token from app1 with iframes or any other method, then this app should be redirected to login and make the process again as app1, which is fine for us.
But is this really the way? if token is invalid anymore and we get Error from backend, should we redirect to the login app in the other subdomain (embed the url we wanna go back to after login success)?
Can i just use 3rd party Open id connect service?
Should i consider microfrontends approcah to make the all the "apps" on the same domain?
How "Attlassian" as an example handles this process?
What am i missing and what is the best way to solve this flow?
Lets say i go to the login app and log in, getting accestoken from the backend. How do i deliver the token to app1.company.com?
It is not a problem that login.company.com delivers the token as a parameter in the URL, because the site can verify the authenticity of the token by verifying the digital signature or with a specific endpoint in the central authentication domain. This is how openid/oauth2 does it using the "implicit" flow, although they also allows to send the token as POST, or use a 2-step flow ("authorization_code" flow)
Lets say the user want to go to app2. if we aren't able to share the token from app1 with iframes or any other method, then this app should be redirected to login and make the process again as app1, which is fine for us. But is this really the way?
You can share the token between domains using an internal iframe, but in your case I would recommend that each domain use its own token.
if token is invalid anymore and we get Error from backend, should we redirect to the login app in the other subdomain (embed the url we wanna go back to after login success)?
Yes, in the number 2) of your drawing, just redirect from app2.company.com to login.company.com and follow the same flow as in 1). You will need some type of cookie on login.company.com to avoid requesting credentials from the user again
Can i just use 3rd party Open id connect service?
Yes, you can use an external OpenIdConnect service, or deploy at login.company.com an OpenIdConnect server like IdentityServer or KeyCloak
Should i consider microfrontends approcah to make the all the "apps" on the same domain?
It is not necessary having a central authentication domain
How "Attlassian" as an example handles this process?
I don't know exactly how Attlassian does it, but currently most web services support OpenIdConnect
In a .NET app I can add authentication and authorization using web.config and/or IIS. I can also use [Authorize (Roles = "RoleABC")] in a MVC app's controller or action. And even extend the AuthorizationAttribute
I'm looking into creating a React app for intranet use, and reading these tutorials (ReactJS and MS), but can't find authentication/authorization details.
Even though the app will be Single Page App, I still would like to authenticate and authorize users for certain options within the app, just like I can do in MVC app.
Is the only option to do that way is creating Blazor app instead?
For authentication and authorization, you should use auth tokens (like JWT). Your backend should create an auth token when a client logs in to the system and sends it to the client. Your server also should send the authenticated user information to the client (react app) so that you can render correct pages according to the user type. For example, you can render the admin page for an admin type of user, and the guest page for a guest type of user. You can save this user data as JSON in Redux. Hence you can access the user data from any component of your react. Also, in your backend, you must restrict the endpoints according to the auth token which is sent by the client. In the backend of my app, I follow the below steps:
Authentication check -> Authorization check -> controller (endpoint) -> result
React isn't opinionated on this, so it's up to you to design the implementation. A basic way to do this is:
Log in and obtain an authorized JWT token from the backend and include the account ID when you sign it
Store the JWT token in localStorage, store the account info in Redux
Conditionally limit routes based on account info (ie. admin group) on the front end
Have every auth-required API call include the JWT token in the x-auth-token header, then on the backend use middleware to check if it's still valid. You can then also decode the account ID in order to check its privileges so that you can limit API access
This may be helpful: https://medium.com/#faizanv/authentication-for-your-react-and-express-application-w-json-web-tokens-923515826e0#5f52
Not sure whether you still need this - I personally feel we should have something bridging the authZ gap between server and client to make it easy. So I spent a few days on a github project for this purpose, here it is: authzyin.
What I tried to do is to leverage policy based authorization from asp.net core - which I think it's very cool - and automatically bring the same definition to the client to use in React via hooks.
For authentication I am using msal.js against AAD - so authN is done on the client and jwt bearer token auth is used for all requests.
It has a client lib and a server lib which can be used together or separately. Of course it might still be lacking some features - please feel free to take it as a reference (contribution is also welcome).
I am currently following this user guide for adding a custom policy to my B2C sign up process
I have created the API and configured the various XML files. I can generate a token to access the API via the implict flow.
The API is secured under the app service with Azure Active Directory authentication.
The page linked to describes how to add basic authentication and a client ID / secret, which is a Client Credentials flow, so I was trying to test this in postman
However, having failed to get it to work I went looking and found a variety of posts stating implict credentials are not supported by Azure B2C?
If that is the case I'm puzzled how it is I'm supposed to ensure the claims of the API I am calling to carry out the business logic can be accessed by the custom policy?
My API is hosted on Azure in the same subscription. I can generate tokens for this API fine to use within my native / client app.
Please could someone advise how I should go about testing access to this API from a B2C context via Postman?
The page linked to describes how to add basic authentication and a client ID / secret, which is a Client Credentials flow, so I was trying to test this in postman
To be exact, it should not be called Client Credentials, because it isn't it.
It's just HTTP Basic authentication.
You are adding an alternative authentication method to your API in that case.
The fact that B2C does not support client credentials auth does not matter here.
What matters is that you have enabled AAD authentication on App Service.
This will block the calls that try to use Basic auth against your API.
Here are a couple options that you can do:
Disable authentication on the App Service and implement the two alternative authentication methods in your API code
Allow anonymous calls through from App Service auth and implement Basic auth for unauthenticated requests in your API code
As for testing from Postman, it should then be the same as testing any API supporting Basic authentication.
You don't authenticate against B2C, so there is nothing special about it.
I am developing web application in React and Django(Rest Framework)., i want to users can login with google account.,
I approach i followed is implicit grant flow.,where i get the access token in the front end., and sent the access token to the back-end. then the back-end should verify the access token with google., and return the new jwt token for future requests. once the user logged out., same cycle continues.,
By My client don't want repeat the same implicit grant flow for other devices(mobile for example)., they want authentication to be handled entirely by back-end. so i am planning to use code exchange flow.
the approach i am planning.
user clicks the login with google button
send the request to django back-end, get the clientId and server callback URL.
client redirect the request to google with the client id and callback url.
google ask permission to users and sends the access token to backend.
In the above approach the connection between client and server is broke in step 3., how to we know the back-end got the access-token. user logged in?