Spring Cloud + Zuul + JWT for Value/Reference Tokens - spring-security

After reading the article How To Control User Identity Within Microservices I've been trying to implement such access control scheme (Value and Reference Tokens), but after going through multiple other topics and examples in GitHub related to Spring Security + OAuth + Zuul, I couldn't find concrete examples on how this can be achieved. All the examples that involve JWT return User Details when the token is returned, and that is what I would like to avoid. The User Details should never reach the Client directly but should be passed to the backend services instead. The tutorial Spring Security + AngularJs has a lot of information on how to evolve an application towards a secure one, but uses an Access Token or mentions the possibility of getting the User Details directly via JWT.
This SO question, Using Zuul as an authentication gateway by #phoenix7360, is exactly the approach I've been trying to implement but it only supplies a brief overview of the configuration required to carry out this kind of security approach for microservices. Please refer to the image in this question for a clear picture of how it would go.
I can't fully get my head around how the Zuul Pre-Filter should be configured and what the Authorization Server's configuration should look like. As stated in both the article and the SO question, the flow would go something like this:
External (HTTPS)
The client authenticates against OAuth2 Server
OAuth Server returns an opaque Access Token (a UUID with no other information)
The client sends the request to the API Gateway with the Access Token in the Authorization header
API Gateway requests User Details to the OAuth Server with the Access Token in the Authorization header
OAuth Server checks the Access Token is valid and returns User Information in JSON format
Internal (HTTP/S)
API Gateway creates a JWT with User Details and signs it with a private key
API Gateway adds the JWT to request and forwards it to Resource Server
Resource Server verifies the JWT using API Gateway's public key
Note: API Gateway should return an error if OAuth Server indicates Access Token is no longer valid.
How would the ZuulFilter work? Does a new request need to be issued against the OAuth Server (for instance, via RestTemplate), or are these schemes supported with the current implementation? Is there any particular configuration required for the JavaConfig classes for both OAuth and Zuul? If someone knows of a working example that would be really helpful and would be great for future reference regarding this topic.
I'm using Spring Boot (1.4.0-M3) + Spring OAuth + Spring Cloud (Eureka, Ribbon, Zuul)
I know this question is very similar to the one linked previously, and if this is not the right way of doing it I apologize, but I thought a new thread would be better than asking for help on a SO thread that aimed at solving another problem.
Thanks in advance!

JHipster does a pretty good job in handling this issue. If I want to tell the login process briefly, first you do login, in time you fetch every information you need to pass to your below services (such as username,email,etc) then you pass them to your microservices.
you can see the link below from okta for more information
https://developer.okta.com/blog/2018/03/01/develop-microservices-jhipster-oauth

Related

Inject OAuth2 token via reverse proxy

We have a service that sends delivery notification messages to a client via HTTP requests - meaning, the client must also act as a Server (must expose an HTTP endpoint) in order to receive these notifications.
Some of our clients are asking that our requests authenticate against their endpoints via OAuth. We would prefer to implement this using a third-party so as to avoid having security features implemented in-house (and avoid security issues/not well-handled edge cases that we could end up introducing); More specifically, we'd prefer to have a reverse-proxy.
The idea would be that our service would send a request to the client through the reverse proxy, which would identify that the request is missing a token and would be responsible for getting a token and injecting it into the request.
I googled for this but couldn't find anything; perhaps I'm not searching for the correct keywords. Is there a packaged/"market" reverse-proxy solution for this? Or perhaps a programmable reverse-proxy that could bootstrap a solution for us?
I can see two approaches for this:
have an oauth2 client library in your own code to handle the oauth2 authentication flow for your app. Most programming languages have an oauth2 client so you wouldn't re-implement anything and have a secure authentication mechanism,
use a proxy that implements an oauth2 client so it would do that part of the flow for your service but I'm not sure it exists. I couldn't find anything also related to this because of the fact that most of the languages have an oauth2 client that's readily available.
I hope you find the solution to your problem :)

Make existing form-login application also serve as an oauth2 authorization server?

We had an web application that already using form-login provided by spring-security, say, ERP. Now we are considering make ERP as an oauth2 authorization server to authorize other internal services.
The ERP still serving its business and all access are required to be authorized, but doesn't based on access token so I think it is not an oauth2 client. It does NOT serve as an Resource Server, neither.
I have read many article about how to setup oauth2 authorization server and develop an application using it. According to this comment I feel it is possible to make ERP authorizing other services without explicit setup a standalone authorization server (it's our final goal but not now):
Within the context of OAuth2, we can break things up according to the component you're implementing:
Client app: it's likely that server based OAuth2 Client app already uses HttpSession and therefore it makes sense to use Spring Session and benefit from all the goodies it brings
Resource Server app: since this component provides a stateless API that's authenticated against using an Access Token as a bearer, the HttpSession is not used and therefore Spring Session isn't suitable as well
Authorization Server app: it's highly likely that this already uses HttpSession so similarly like with OAuth2 Client app, it makes sense to use Spring Session and benefit from all the goodies it brings
What I'm going to do is add the #EnableAuthorizationServer into config, but I have no idea what's the next step.
My question is can I convert an existing application into an authorization server while keeping its original service unchanged? Where and How should I start?
I just found it's not that hard to integrate OAuth2 into existing system, below is what I did to make it work.
In short: EnableAuthorizationServer won't break anything exists, but they don't coming from nothing, either.
When I put on the EnableAuthorizationServer, spring-security-oauth2 gives me following endpoing:
/oauth/authorize
/oauth/check_token
/oauth/token
/oauth/confirm_access
/oauth/error
Those endpoints provide necessary functions to make OAuth2 works, and I just need to apply access control onto those endpoints with existing form login mechanism (probable not the check_token one).
Since this system didn't act as resource-server role, the authorization part is done.

Access Token/Authorization Between Microservices

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.

Questions on OAuth 2 server in ASP.NET Web Api

Currently, I think my understanding of OAuth and how it it is implemented in ASP.NET Web Api is flawed.
1) I keep seeing OAuth described as a server (i.e. the OAuth server). Is the OAuth implementation by a Microsoft a separate server with a different port or is it just referred to as a server even though it is self contained within the API project?
2) Is OWIN separate from OAuth or are the two linked such that they must be used together?
3) How does an OAuth v2 server keep track of tokens that have been revoked or have expired? Does the OAuth component have a database that keeps track of the tokens that it issues? If so, what type of database is it?
I have been reading the tutorials by Taiseer Joudeh from bitoftech.net but I think I am missing some of the basics.
Here are my responses:
You can implement the server as a stand alone authorization server or you can implement it together with the resource server. The Visual Studio template brings you both servers together, but you can separate them. Tutorials from Taiseer Joudeh will guide you very well, they did in my case.
OAuth 2.0 is an authorization framework, as said in its definition document. And OWIN stands for Open Web Interface for .NET. Both of them are different things, but Microsoft decided to do an implementation of OAuth 2.0 protocol using OWIN middlewares architecture. Then the easiest way to develop OAuth 2.0 servers in ASP.NET is using Microsoft.Owin.Security.* libraries implemented by Microsoft.
The OAuth 2.0 protocol does not talk about keeping track of expired or revoked tokens, you could implement if you want, but you only could do if the authorization and resource servers are both the same, and then you will need to access to database to check the token for each request, that it is not necessary. If the resource server is separated from the authorization server it has no direct access to the authorization server database. Normally you don't do that. The expiration check of the token is something that the Microsoft.Owin.Security.OAuth library makes for you. If a token received by the resource server has expired, the library responds with a 401 - Unauthorized response.
To make possible that the resource server can decrypt the token, you only need to set the same machine key in both servers' web.config file.
To avoid to have long lived access tokens you could set short access token timespan and implement refresh token. In this case, you could save refresh tokens in database and you can implement some method to revoke them.
Refresh tokens and its revokation are implemented in Taiseer Joudeh blog posts too.
I hope my explanations are clear and can help you. Please tell me if you have any other doubts.

Spring Security OAuth2 - Custom Authentication

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.

Resources