I was wondering, if one were to use Spring Security with Spring data rest, would it be possible to partition the data so that the user of the REST API can only say data related to them?
More specifically, assuming Spring data ne04j exposed over HATEOAS with Spring security. If the client is given an oauth2 token, can that token be programmatically used to only give the user the subset of the graph that he created or related to him?
E.g. A Bank is exposing some actions on a account. The client is given an oauth token. The client should only be able to see and perform HTTP operations on their account, and not any other user.
By default, once you have access to the HATEOAS endpoint, you can see all data. Is there anyway to limit this, without too much heavy lifting?
You can use #PreAuthorize to perform authorization checks before an operation and #PostFilter to filter the returned data.
Some examples:
#PreAuthorize("#contact.name == authentication.name")
public void doSomething(Contact contact);
#PostFilter ("filterObject.owner == authentication.name")
public List<Book> getBooks();
Related
I'm creating an online store REST API that will mainly be used by a mobile app. The plan is for a microservices architecture using the Spring Cloud framework and Spring Cloud OAuth for security.
My question is really on best practices for communication between microservices: Should I have each service register for their own token, or should they just pass the user's token around?
For example, I have 3 services: user-service, account-service, order-service.
I've been able to implement two procedures for creating an order: One passes the user's token around, and in the other each service gets their own token. I use Feign for both approaches.
So for option 1: order-service -> GET account-service/account/current
order-service calls the account-service which returns the account based on a userId in the token. Then the order-service creates an order for the account.
Or for option 2: order-service -> GET account-service/account/user-id/{userId}
order-service gets the userId from the sent token, calls the account-service with it's own token, then creates the order with the retrieved account.
I'm really not sure which option is best to use. One better separates information but then requires two Feign Clients. However the other doesn't require the 2 clients and it becomes easier to block off end certain endpoints to outside clients, however it requires extra endpoints to be created and almost every service to go digging into the Authentication object.
What are all your thoughts? Has anyone implemented their system in one way or another way entirely? Or perhaps I've got the completely wrong idea.
Any help is appreciated.
I have found below 3 options:
If each microservice is verifying the token then we can pass the same token. But the problem is - in between same token can be expired.
If we use client_credentials grant then there we are having two issues: one is, we need to send the username/id in next microservice. Another one is, we need to request two times - first for getting the access token, next for actual call.
If we do the token verification in API gateway only (not in microservices) then from the API gateway we need to send the username in every microservices. And microservices implementation needs to be changed to accept that param/header.
When you do server to server communication, you're not really acting on behalf of a user, but you're acting on behalf of the server itself. For that client credentials are used.
Using curl for exemple :
curl acme:acmesecret#localhost:9999/oauth/token -d grant_type=client_credentials
You should do the same with your http client and you will get the access token. use it to call other services.
You should use client tokens using the client_credentials flow for interservice communication. This flow is exposed by default on the /oauth/token endpoint in spring security oauth.
In addition to this, you could use private apis that are not exposed to the internet and are secured with a role that can only be given to oauth clients. This way, you can expose privileged apis that are maybe less restrictive and have less validation since you control the data passed to it.
In your example, you could expose an public endpoint GET account-service/account/current (no harm in getting information about yourself) and a private api GET account-service/internal/account/user-id/{userId} that could be used exclusively by oauth clients to query any existing user.
I wrote an API in rails which is of micro services architecture.
In my API i need to implement Role authorization to authorize each and every user using their roles.
Is there any gem that fits into micro services architecture or should I write my own logic to authorize users.
i was using gem authorization gem but it does provide much capability that fits into micro services architecture.(rolify)
Is there any other that suits micro services architecture?
Thanks in Advance.
Whenever you have to implement MicroServices in Rails, then I prefer to put your authentication and authorization (role based permissions) using JWT (JSON Web Token). Because in MicroServices, there are multiple different projects which are deployed on different servers and communicating with each other through APIs and you require only one API Gateway, where user provides the login credentials and its should work for all different projects. I wont prefer devise because it creates a session after successful login which is Stateful, while JWT is Stateless.
Statelessness means that every HTTP request happens in complete isolation. When the client makes an HTTP request, it includes all information necessary for the server to fulfill that request. The server never relies on information from previous requests. If that information was important, the client would have sent it again in this request.
In case of JWT, each request comes with a token something like "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0NjUwOTYxMzMsInN1YiI6MX0.e9yeOf_Ik8UBE2dKlNpMu2s6AzxvzcGxw2mVj9vUjYI" which will contain all required info in its payload for login. Please refer https://restfulapi.net/statelessness.
The token should also include the role or permissions (e.g. admin role) of user and based on role it should fetch the data and its relatively faster than Stateful requests. Because in case of Stateful requests (as happens in traditional Web Apps), it stores the session_id in cookies and sends the session_id with request. So on server side, first it fetches its user info and check whether its valid user, then fetch its role and then after successful authentication and authorization, it fetches requested data. While in case of JWT, since the role and username comes within token itself which would be decoded on server side, and directly fetches the requested data from DB. JWT (or Statelessness) helps in scaling the APIs to millions of concurrent users by deploying it to multiple servers. Any server can handle any request because there is no session related dependency.
Difference between Stateful and Stateless, please refer https://restfulapi.net/statelessness and https://nordicapis.com/defining-stateful-vs-stateless-web-services.
For more info about the implementation, please refer http://pacuna.io/2016/06/03/rails-and-jwt and https://github.com/nsarno/knock.
The devise gem is the leader in the industry. All of its methods are fully customizable - they can be used as a before_action (typical usage but not ideal for micro services) and can also be used as just another method in your code (inside a block, in a 'if' statement, etc). Checkout the github page here
https://github.com/plataformatec/devise
It has so much functionality, I could teach en entire course on this gem. There's a lot to learn if you aren't familiar yet.
Thanks for the Answers guys,
Coming to the answer,i have implemented my own way of authorization.
I had come up with a design where User -> Roles -> Resources -> Permissions
Here the resources are individual parts where every user has some permissions upon using a resource and role has set of defined set of resources with some permissions like
read_only,read_create,read_update etc
Each user can have any number of roles, thus user having a permission to access a specific resource.And i perform this check for each action using
before_action
Thanks,
Suresh
We need to expose a REST endpoint to the outside world to be called by an external service which we don't control. The people responsible for this external service seem to be security experts (not), and so instead of using at the very least HTTP Basic Auth or any other real authentication mechanism, they authenticate themselves using a fixed secret. It goes like this:
GET /endpoint?secret=WE_ARE_THE_TRUE_GUYS
As we're already using spring-security-oauth2, we'd like to integrate this authentication flow with our existing flow so that we can specify rules for this endpoint the same way we do for every other enpoint on our ResourceServer, get the same error handling behaviour and etc. How shall we go about implementing a custom authentication filter - or whatever it may be - that will grab the secret parameter from the query string, transform it into some kind of "client credentials" for a pre-configured client on the AuthorizationServer and integrate seamlessly with the rest of the OAuth2 flow?
If you can transform "WE_ARE_THE_TRUE_GUYS" into a valid OAuth2Authentication then all you need is an authentication filter that does that (and sticks it in the SecurityContext). Then the downstream filters and handlers will behave just as if it was a real OAuth2 authentication. If I were you I would put some very tight conditions in that filter to match the request to one that is on the allowed resources from this highly unusual and not very secure authentication channel.
I have question related to authorization and spring security. To implement authorization checks in one of my services (under a Service Oriented Architecture environment), I was trying to see if I can use Spring-Security. While going through the Spring Security documentation, I read here that spring security uses spring's AOP internally.
Ref: You can elect to perform method authorization using AspectJ or Spring AOP, or you can elect to perform web request authorization using filters. You can use zero, one, two or three of these approaches together. The mainstream usage pattern is to perform some web request authorization, coupled with some Spring AOP method invocation authorization on the services layer.
We are already using Spring AOP in our service implementations. In my case, the requests that will be coming to my RESTful service will carry a custom built token object that should be processed to perform authorization checks.
Based on this, I would like to understand if I can simply use Spring and create an Aspect to catch an inbound request, extract and process the associated (custom built) token and continue/reject the request based on the result ? Do I need spring-security, given that the communication channel is already secured using HTTPS ?
Thanks,
SGSI
For a similar situation we did the following a long time back:
Used an HTTP filter to extract a token from HTTP headers for each request.
Stored the extracted header to thread context.
Added an aspect around service method calls to check the thread context for the token.
This strategy worked well for us. For last many years I have been using Spring Security since it has a more tested and comprehensive implementation for such problems.
If you wish to write your own token-passing implementation, you can check the source code for the Spring Security class SecurityContextHolder that provides multiple ways of passing security information on the execution thread.
What I purposed to do is, I want to do is I want to create a Claim based Authentication.
But I use a public Auth provider such as LIVE connect API.
So it only return OAuth based data to me.
Considered I'm the server side, I just want to
1 get the data with OAuth.
2 convert it to claim.
3 set current principal to the claim I created.
Do I need to create a STS?
And can I use these this claim achieve SSO?
And have a look here where he actually implements it.
Or here which shows how to do it with Azure ACS.
You create Security Token Service (STS) when you want to decouple your authentication logic from your business logic in a way that it works as two separate services / applications, where one is issuing Security Tokens, and the other one (or more of them) are consuming them.
To me it seems that you should implement your own ClaimsAuthenticationManager that will convert all the data received by OAuth (which is doing authentication for you) to claims, generate ClaimsPrincipal with it and add your own business logic claims to it as well => set generated principal to be your current principal.
Depending on what libraries are you using for OAuth, some of them will create initial claims principal for you, which you can then take in ClaimsAuthenticationManager, and convert it to your own claims principal.
For more reference on it, check www.leastprivillege.com, Dominick has nice series of articles about OAuth and claims based authentication.