How would I apply OAuth2 in the following scenario:
I have an app that has to connect to an external service that used OAuth2 authentication. The resource owner is not the user of the app, but the app itself (so there is just one account that should be used by all users of the app). In this case, we can not show the user a login screen to connect to the external service. How do I apply OAuth2 in this scenario?
Form your explanation it appears you should use the client_credentials grant_type.
Or as you tagged with "Google" perhaps use the OAuth2ServiceAccount
Related
Our OAuth client application is built with Spring (through JHipster). The OAuth provider only serves the authentication functionality, but not the authorization functionality. Ideally, we should only allow a small group of people to access our OAuth client application, but not all those users who can sign in to the OAuth provider.
A solution I can think of at this moment is to create a custom user role to control the access in the OAuth client application. That, however, only can be done after the user's first sign-in when the user account data is created in the application.
Any better solutions?
Ideally you would apply user access control before creating user account data is created in the application. You could do so by providing an application specific scope or claim in the token that is generated for your application (aka. Client). Upon receiving the token, the application would check for the required attribute in the token before allowing access.
How do I best configure Keycloak so that a user needs to have an account for a client to be able to login into that client?
I have to replace a proprietory SSO-Impl. It deals with users, roles and clients much like Keycloak. However, it also knows about accounts. A user is only allowed to login to a client if he has an account for that client.
In Keycloak, if a user simply exists in a realm he may login to a client of that realm. Nothing else is needed. So no "account" is needed. In the old application, he needs an account as well.
What functionality in Keycloak is best suited to overcome this difference?
I have one idea:
Create a client-role in each client namend "HasAccount" and assign it to users. Then, restrict access if that role is missing.
This is discussed here: "Restrict client access in a single realm with keycloak"
It has at least two drawbacks:
It mixes authentication and authorization in the legacy app. I can understand that. But creating a role was already a workaround. That is why I described my initial problem here.
I have clients in 3+ languages/technologies. Adding functionality there seems like more work than in Keycloak.
Last remark:
Before you ask "This is not single sign on" anymore. It is only for administrative purposes. The admin can allow users to login into a client or not by creating an account or not. The user does not have to login a second time. If he is logged in in App A and has an account for App B, accessing App B works without logging in there.
A user is only allowed to login to a client if he has an account for that client. is really not a task for Identity Provider (IdP). It provides only identity and not authorization.
Of course you can ignore that and implement authorization as well. See: User attribute based web service access control by Keycloak
From the design perspective I would add auth reverse proxy in front of legacy app (but it isn't a best solution for SPA apps). Auth proxy will provide authentication via OIDC protocol and also authorization. Legacy apps may keep own OIDC authentication - it will be seamless auth from the user perspective, because SSO will be used.
Account entity - you can use group entity in the Keycloak instead of original account.
We've implemented OpenId Connect for our UI front-end login using user credential flow, which redirect the user to a login page.
We would like to use OpenId Connect for our B2B APIs without the redirect flow.
B2B API user are not trusted, can not be provided with the client secret
B2B API are mechanized, need to login without redirect to login UI page
Is there a flow were 3rd party user can login and receive an access/ID token and pass it to the our API?
What is the best practice for such scenrio?
Thanks
To answer this properly it is important to identify the precise client side usage, since solutions are always driven based on this.
SCENARIO 1: OAUTH CLIENT IS A BUSINESS PARTNER'S BACK END
B2B APIs are most commonly called from code written by a business partner, perhaps in their own Web API. In this case the Client Credentials Grant is used, and it is possible to use Mutual TLS based forms of this for higher security.
A common setup is for the business partner UI to call the business partner API, which can then return data from your B2B API.
SCENARIO 2: OAUTH CLIENT IS YOUR OWN UI, USED BY BUSINESS PARTNER USERS
In this case the moving parts are as follows:
User is redirected to authenticate to your app
Your Authorization Server handles the redirect and issues tokens
Your UI and API use tokens from this authorization server
It is possible for the Authorization Server to perform a further redirect, so that users from business partners can sign in with familiar credentials. My Federated Logins Blog Post describes how this is configured.
YOUR SCENARIO?
If the above does not answer your question, please describe your scenario in more detail:
Why do you want to avoid the redirect?
Is the user logged in to their own app already?
At my company we are developing several web applications that uses a REST API server.
First a little introduction.
The app provides the ability to manage users through the REST API and allows the users to login to the app.
Right now the REST API is for internal use only because we plan to develop more apps and communicate to the REST API as the central point of data access. We are handling the REST API authentication with a "Resource Owner Password Credentials Grant" implementation for the internal apps.
What we need is a Single-Sign on service for all the apps, we want a user to login to an app and if he/she access to another of our apps he/she will be already loged in.
We have been experimenting with the CAS protocol, with the CASino library specifically and it works great.
The problem is we don't know how to handle the flow between the apps, the REST API and the SSO service, also I don't know if there is a better choice regarding SSO services.
My questions are...
How we could handle the flow between the apps, the REST API and the
SSO service, because the REST API should be stateless it should not
communicate to the SSO service? or is there a way to communicate the
REST API to the SSO service?
Is there a better choice to implement a Single-Sign on service,
maybe OAth or OpenID and are this options suitable for REST APIs?
Thanks in advance!
Your REST API will have to talk to the SSO server to validate the Access Token, unless all the information it needs is encrypted inside the Access Token. Not sure what you mean by "flow between the apps", you should have all apps talking to a central SSO server.
When a user wants to create an account on WebApp1, the account should be created on the SSO server, either by redirecting them there or if you need a differently styled signup form for each web app, then via an AJAX call to the SSO server's REST API. I would recommend the latter as redirecting is more difficult to debug and it can make a bad user experience.
Make sure the messaging is clear, i.e. not "Sign up for a WebApp1 account", but "Sign up for a MyCompany account to get access to WebApp1".
OAuth 2.0 is very popular and people have more experience with it, so it's easier to get help or integrate with apps created by others.
The doorkeeper gem is a good server library.
OAuth 2.0 is normally used when the SSO server doesn't trust the client apps (e.g. Facebook, Twitter), but it can be implemented in such a way to skip the client authorization step (where the user is asked to approve the client app), and you can use the Resource Owner Password Credentials Grant via a REST API.
CAS is easier than OAuth. It is fairly easy to implement the basic endpoints and that way you can customize it as you wish.
I worked on a CAS-based server with a custom implementation (not sure if it was even really CAS-compliant). The authentication was done with Devise (I don't recommend Devise if you're going to customise it a lot, make your own in this case). The original flow was that the user went to the website, clicked Login/Register and then was redirected to the SSO server and after the user logged in, redirected back with a one-time ticket that the website's backend exchanged to an access token via a REST API call.
Then we added a REST API that was called from each website with AJAX. You send the username/password/captcha/etc and get back an auth token, which the site sends to its own backend. The SSO REST API can also set a cookie on its own domain, so that if the user visit another of our web apps it makes a call on pageload to check if the user is logged in. This way you're automatically logged in on every webapp without the redirect mess.
All tokens issued + the associated user info were sent to a fast Node.js app that would save them to Redis, and the app backends would call this app to validate the access tokens really fast, without putting load to the SSO Rails app.
I want to ask this question, because I am not sure if I understood the whole OAuth2 process completly:
The scenario is that you have a app and want to do a registration for a new user inside that app. From the users point view it would be stupid to just re-login after the he created the account.
My idea was to use the "Password Flow" directly and instead of just submitting a password, submit the whole user registration data. But it seems a little itchy to me, so what is your opinion about that?
OAuth 2.0 is a flow to allow third-party applications to access end users' resources which are hosted at another service.
In your scenario, both "the client application that accepts a new user's ID and password" and "the service which manages the user registration information" are owned by you. In this case, you don't have to refer to OAuth 2.0 specification. Instead, implement your client application and your web service as you like. If the client application is not yours, you should not allow the client application to accept the user's ID and password directly.
When in the future you think of allowing third-party applications to access your service, it's the time you need to read OAuth 2.0 specification.