Use case
I have three microservice A & B. A is external service exposed to user and B is internal service, called from service A
User --> A --> B
User is initiating the request from browser and passing the Bearer token to A ( Already logged into using some method and retrieved the token)
A --> B call is secured using API account ( client credentials). So service B get the client Id of A
But we also need who initiated the request ( User)
Is there any out of box microservice pattern or technique supporting this use cases.
As a workaround I have used the request interceptor, before passing the request to B, A is adding additional headers.
Related
I have a clarification question.
I plan to build an authorization service with spring security and spring authorization server. Say I have multiple instances of the auth services that are behind a load balancer. My understanding is that the following will happen and assume that we have two instances A and B:
when a user is trying to access a protected resource it will first redirect to the auth service (a request to instance A with /oauth2/authorize?response_type=code&client_id=some_client_id&scope=some_scope&state=some_random_string&redirect_uri=http://some_redirect_url/)
the auth service will then redirect the user to login because the security filter finds out the user is not authenticated (response from instance A)
the user will enter the credential with formLogin (at this time the request might hit instance B)
In this case, how does instance B gets all the parameters such as client_id, redirect_url, and so on?
update 1:
do I need do something like this .loginPage("/login?client_id=&client_id=some_client_id") to pass down the information
I have 3 services 1 authentication service(for example service A) and other 2 services(for example service B and service C) which are using same authentication A service.
I have method in service B like
#PostMapping("/update-account")
public ResponseEntity<Object> updateAccount(HttpServletRequest request,
OAuth2Authentication principal,
#RequestBody UpdateAccountDto updateAccountDto){
}
In this method I am calling other method where I have some logic and in the end I want to call endpoint of service C using restTemaplte like this
String serviceBEndpoint= "localhost:8090/testapi/updateAccount";
URI serviceUri = UriComponentsBuilder.fromUriString(changeEmailUri)
.build()
.toUri();
HttpHeaders headers = new HttpHeaders();
headers.set("someheader", someheader);
HttpEntity<UpdateUserDto> request = new HttpEntity<>(updadteUserDto, headers);
restTemplate.postForEntity(serviceUri, request, AuthenticationSuccessDto.class);
User called endpoint of Service B with correct token(request is authenticated) and it is also legal to call service C from service B because request is authenticated, so how can I do it with correct way ?
The most common approach for microservices all owned by the same company works like this:
Client authenticates the user and gets an access token with rights to call both services B and C
The access token might therefore have scopes B and C - or something similar - related to the business of those services
Client calls service B and includes the access token in the HTTP Authorization header
This means service B can forward the token to service C, again in the HTTP Authorization header, and service C will accept it because it contains scope C. Looks like your Rest Template code above is nicely set up to enable this.
Both services B and C need to validate the access token in the standard way - see these guides for exanples.
More on this pattern in this Scope Best Practices article.
I have two microservices say A and B. In all REST endpoints for both microservices, I have implemented JWT authentication. A user has to hit an endpoint ("/login") with username and password and generate a token and pass this as a RequestHeader to all end points in both the services.
Say in microservice A, I have an endpoint ("test1/createSomething"). In B I have another have an endpoint ("test2/getSomething"). Now I am able to call ("test2/getSomething") from service B, in ("test1/createSomething") in service A using Feign client.
But I am not sure how to implement this in a way that I generate the JWT token in service A and pass it along to service B, to consume its services.
Please help. Beginner in microservices and exploring things.
One approach you can try is by having a separate session/jwt service.
Roles and responsibility of that service would be to store/validate and authenticate having following endpoints.
create_token() : create new JWT token with given input data(say user info, expiration time etc)
is_token_valid() : check if token is valid or not
So you can have a flow like this :-
1. First hit to login-service > login service getting token from jwt-service > returning jwt token to UI/client.
2. UI/Client passing received jwt token to service-b via headers> which indeed pass jwt token to service-a, where each service independently calls is_token_valid() of jwt-service and process the request only after getting success response.
To implement this in spring-boot, what you can do is by adding an interceptor layer, that is being called before every Controller class, where is reads headers, extracts jwt-token and validates that from jwt-service.
You can look at the similar answer here.
Another reference here
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.
We have implemented a RESTful API using RestEasy. Now we are planning to build our own OAuth implementation and will integrate it with our Rest API.
I do not fully understand how OAuth handles authorization of every request to the API. My understanding is as follows:
User is authenticated by the OAuth server before any REST API calls are made.
Every REST API call will contain a token. The REST API server validates this token with the OAuth server. If the token is valid then the server will return a response.
This should have an impact on performance as we are validating the token for each and every API request with the second server. Is this understanding correct?
This will depend on how you will define your REST API. Basically OAUTH call has following components.
User: Who makes a request.
Provider: Who holds user information and provide apis to access them.
Consumer: Who asks the user to authorize the consumer to make request to the apis.
The basic workflow is as follows,
User tries to access restricted resource from Consumer.
Consumer asks user to share some information about him.(scope)
User selects his identity provider.
Consumer should be known to the Provider.(Usually consumer register itself as an application/website in provider's portal)
Consumer redirects to the provider with his consumer_key and scopes.
User authorize the application and grants access to some of his resource.
Provider creates a token and redirects back to consumer.
Consumer exchanges this token and its identity to get a access_token for user.
Consumer uses the access_token to make authorize request to provider and asks few information about user.
Provider sends those information to consumer.
Consumer verifies the information and user is logged into the system.
Now each token is generated against the scope and will be valid for some days. Token validation will be part of response from Provider.
In your system, you can store user data against token, so that we need not request Provider to send those information. But if you dont want to store user information certainly there will be additional calls.