Users,Roles and permissions in spring boot - spring-boot

I want to register users. Now each user has 2 different roles- Role1 and Role2. Role1 can access some APIs. Role 2 can access some other APIs. I have to implement this using microservices. Can my microservices be these-
Register microservice (To register all kinds of users)
Authentication and authorization microservice (that authenticates the users as valid or invalid and authorizes them based on the roles)
Role1 microservice(with all its controller methods)
Role2 microservice(with all its controller methods)
Now Authentication microservice would need the registration details to authenticate the user so can that be done using open feign client
also is it possible to have a separate service for each role and secure the APIs based on roles with authentication and authorization as a separate microservice? If no then what can be an alternate solution

Is it possible to have a separate service for each role?
Ideally, you shouldn't create the microservices based upon the role. Introduction of more roles & you will end up with as many as services.
Can my microservices be these-
Register microservice (To register all kinds of users)
Authentication and authorization microservice (that authenticates the
users as valid or invalid and authorizes them based on the roles)
Role1 microservice(with all its controller methods)
Role2 microservice(with all its controller methods)
There're many ways to fulfill the requirements while keeping the design principles intact. One such way, you can go with auth-service, user-service and third-service (say).
auth-service: This service will perform authentication & authorization by verifying the user details. This service can also held some minimalistic data to validate the user identity and therefore, it don't need to rely on user-service during the login process. Your auth-service issue some sort of token once user get verified. The token could be an opaque token or JWT. If your auth-service can issue JWT containing the role details then even your third-service don't need to rely on auth-service.
user-service: This service will contain all the user information and your third-service can talk to it to get some details while performing its operations.
third-service: This service will act as resource-server having the protected resources available to different roles. If the token is JWT, this service will verifying the token and get the details from it. In case of opaque token this service need to talk with auth-service to verify the token and get the role details. Once you've the role details, you can write some validation code in the controller to check the access based up on the role and take a decision to allow or deny further access.

Related

What is the advantage of providing a Tokenized Authentication in an application with Spring Boot Backend over SecurityContextHolder?

I was getting started with Spring Boot and Angular 7 and I came across user authentication.
Let's assume the following: I have a frontend with Angular 7 and a Backend with Spring Boot that offers API's that can be accessed via HTTP.
So I know that usually the frontend authenticates the user with e.g. JWT that stores all necessary information about the user that might be needed. But I came across the SecurityContextHoler of Spring Boot Security:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
This allows me to simply access granted Authorities and so on. So I thought about the following:
Using JWT for the frontend grants the following advantages (as far as I know):
* Users can identify when using API's
* Users may be prevented from certain UI-Elements (based on roles stored in JWT)
* Modification prevention due to checksum (invalid token afterwards)
Now I could also add a check in my Controller in the Backend that checks the SecurityContextHolder for user permission (something like a Service that checks the current context permissions vs the needed permission and returns true/false). Wouldn't that be even more save, since it is in the backend (so in my inmagination everything that runs server-sided is always a little more save than what runs client-sided)?
I can store information in the frontend (like roles and a username) to use them for the UI-based-access prevention to still have the same advantages as JWT provides, but I do not have the "effort" of implementing the JWT creation.
But obviously it is not common to do it that way (at least I never saw it), so what is the advantage of the Tokenization?
They are not mutually exclusive. You would use what you call "Tokenized Authentication", like an oAuth2 Bearer token most likely in a JWT when the Authentication is performed by a separate system from your Spring Boot backend. For example, you may be using Okta, Keycloak, Google or Facebook to authenticate the user.
At a minimum, your Spring Boot backend stores the username extracted from the JWT in the Authentication. You can get Spring Boot to extract any roles in the token and add those to Authentication::grantedAuthorites. If your backend system, has it's own set of roles in addition to what's in the token, then the backend could implement a PrincipalExtractor to load a UserDetails object for this user from the database as the Principal and merge the roles in the token with those store in the local database.
You'll probably want to security certain methods in your backend with method security annotations like #PreAuthorize(), since you shouldn't trust the front end. The method security will check permissions, like hasRole("ADMIN") or hasPermission(object, 'READ') using the Principal object in SecurityContextHolder.getContext().getAuthentication();
In the end, the token assures the backend the user accessing it is who they say they are, i.e. Authentication, but does not necessarily tell the backend what they are Authorized to do. Yes, if you control the Authentication server you can include roles in the JWT, but roles don't usually provide as fine a grained control as is required.
Independent of what level of security you implement, the token is translated into an Authorization so you can use the Spring Security framework to manage access within your backend code.
There are 3 type of token in spring security OAuth2:
1. InMemory token Store
2.JWT token store
3.JDBC token store
So now you’re talking the JWT token store. The most powerful of JWT token store is prevent the authorization server load against to the database for checking such as role,token expired so it is related database load performance. Since all the information such as: role,username, token expire ,etc include in token itself. So the authorization server or other resource sever may using the public key to verify this token itself without invoke to data store.
Hope helpful! ☺️

UAA Federation: How to return group information back to relying party?

After configuring two UAA instances as federated, say UAA1 (Relying party)--uses--> UAA2(ID provider) through OIDC mechanism, I can use UAA1 to authenticate users defined on UAA2 through authentication code work flow. UAA1 defines shadow users in its instance, but it does not capture groups defined for users on UAA2.
For example, user1_uaa2 is on UAA2 and it belongs to a groups called uaa.test. After login through UAA1, a shadow user user1_uaa2 is created in UAA1, but its group information is lost.
How can a user's group information be propagated back to relying party in OIDC based UAA federation?
Thanks
I think according to source code, that in last version of UAA (V4.10), UAA only returns openid as scope in id_token and /userinfo, no matter if the access token has roles scope or not. That means as either OIDC or SAML identity provider, it does not provide user group information.
It seems to me its codes work and are able to retrieve group information when UAA works as SP or proxy to other IDPs. It store those information to user_info table.

API gateway and microservice authentication

How API Gateway and Micro services works.
Could anyone explain the basic flow of Micro service architecture with Gateway. I couldn't find the proper answer.
Say we have auth server and customer micro service running on separate instances and in front of all the services we have an API gateway.
My question is.
when user try to log in using username and password, the API gateway call auth server and return the access token to user.
Then user trying to access the specific url (/customers - customer micro service) that is running on separate instance.
what API Gateway do ?
validate the token with auth server and get the user id and pass the request to customer service with the user id ?
OR
validate the token and pass the request to customer microservice with the access token ? and customer microservice responsible is to the check the user id (Make an HTTP call to auth server) ?
I think that the most common approach is to use API gateway also as a security gateway, which means that API gateway is responsible for SSL termination and token validation. If token validation is successfully you can put user ID or user API key as a header and forward the request to microservice. Moreover you may also decide to perform not only authentication but also authorisation on the API gateway (usually with help of API management solutions).
Regarding your option #2 - I see no point in validating token 2 times. Best practise is to perform security validations on the edge, because in case of failed validation you use less resources (reject earlier)
To Answer your question , it is close to option #2 that you have mentioned . The API gateway will generally check the validity of the authentication token and then pass over the request to your micro-service . However you need to decide at design time if your micro-service will also do another level of verification of the token.
Please do note that the API gateway will not be enforcing Authorization , the authorization is something that your micro-service will have to enforce.

How to architecture Microservice & OpenID connect?

We have three microservices: microA, microB & microC.
microA & microB are powering product 1.
microA & microC are powering product 2.
Obviously, we would need a security layer, in our case implementing an "OpenID Connect" provider fits well with the business needs. We add to the stack the OpenID provider.
The user/rights management is quite easy & natural: we associate the OpenId identifier of the user on each microservices to a subset of rights:
For example on the service microA, we store that the user OpenID XXX can do this and that. it's isolated on the microservice level. Respect the boundaries of our context. Fine.
When the user login with OpenID on product1, we grant an access token to the user + an Id token.
The situation becomes more complex when product1 expose an API that third-party use.
Now, let say that my user comes to the third-party webapp and is prompted to login & allow the third-party to get some rights on product1 API.
If I understand correctly OpenID connect, it's all about authentication over OAuth2, but how do we handle classic OAuth2 scope management then?
The best scenario I have found is:
make the whole OpenID connect to have the authentication info
and then make another full OAuth2 process to another Authorization server to ask the user to grant some scopes to the third party?
which means that on the third-party:
the user will be prompted to login on the OpenID Provider
then redirected and prompted to accept the scope requested
Is that correct? If yes, OAuth2 server flow is like 4 HTTP requests to the end user, so performing it twice is like executing eight requests to get the Authentication + Authorization flow done. Seems too massive.
I've already had this problem. What I would do in your case is:
Use this new OpenId microservice to authenticate the user and create the access-token. This access token can be a string with the permissions, user_id and the timestamp signed or you can store this info on a database.
Then, for every call (to product1 or product2):
I would force the client to send the access-token on the headers.
Then, when a microservice receives a call (lets say product1), I would send a signed request to the OpenId Microservice to ask if the user is allowed to perform that action.
That way, just the OpenId microservice knows how authentication works. So if in a couple of weeks you want to change how authentication works, you just have to change it on the OpenId microservice.
I dont really understand whats the problem with third-parties. They will get the token and they will be able to perform calls passingit on the Access-token header.

Difference between scope and authority in UAA

In UAA There are two Concepts, Authority and Scope.
These concepts seems to overlap. I would like to know exact difference and purpose
For example , oauth.login
Scopes are permissions of an OAuth Client acting on behalf of a User. They are granted after obtaining a user token with one of the following grant types: auth_code, password, implicit. Scopes signify what the application is allowed to access on User's behalf (referred to as delegated authorisation).
Authorities are permissions of an OAuth Client acting on its own behalf and there is no User involvement. They are granted after obtaining a client token with grant_type of client_credentials. Typical use is an Application or API trying to access a resource with its own credentials without user involvement.
In UAA , oauth.login is a system level permission and was being used by the legacy implementation of the login-server project (When UAA and Login Server were separate components). This permission allows admin level access for login server.
1) authorities and roles are spring-security wording for permissions. It is not defined in OAuth2 specs.
2) scopes are defined by OAuth2. It is intended to define what the end-user allowed each client to do on its behalf (information from authorization-server to resource-servers).
As a consequence, authorities granted to a client should always be a subset of end-user ones : all possible scopes => all of user authorities ; the less scopes, the less authorites.
One trick, on "client" OAuth2 flow, the client is the end-user => scopes make no sense in that case (the client is not authenticating on behalf of someone, but in its own name).
Default OAuth2 spring-security converters turn scopes into authorities. To me this introduces a lot of confusion and should not happen. Scope claim should instead be used to filter end-user authorities.
Latest requires to write and configure your own authorities converter which is already possible for JWT but not yet for introspection (should come, a ticket is opened for that)
Also, nothing in OAuth2 specs requires permissions (spring authorities and roles) to be contained (using a private claim) in the token or managed by the authorization-server. It is legit for a resource server to retrieve it for instance from a database using the subject claim and then "scope" it (filter end-user authorities according to the scopes granted to the client).

Resources