RoR reverse proxy (oauth) - ruby-on-rails

We currently have the following architecture (for a RoR based production system)
A gateway, which also acts as auth (oauth functionality implemented using DoorKeeper) is the starting point for all requests coming from the front end.
The system is working perfectly well. The task we are faced with now involves addition of a legacy application (written in multiple languages, including ASP.NET). This legacy application currently works fine as a standalone system. What we intend to do is
Integrate the legacy system within our working system (within our own subnet)
Do minimum (or if possible zero) modifications to the legacy system
keep using our oauth layer (gateway) as the first point of contact for all incoming requests (including the requests to the legacy system)
We are in control of the front end requests and routing, so CSRF is not a concern
One solution that we are considering is that the auth layer (gateway) also acts as a reverse proxy. In essence any request coming for the legacy environment (from the legacy front end clients) will be authenticated by doorkeeper but they will now be redirected to the legacy server-application and the response is then send back to the client.
The above sounds like a nginx reverse proxy, but I want a RoR gem which I can use because I want this to be flexible for future modifications. For example (but not limited to)
I can modify the legacy client to start using multiple auth mechanisms (so the request from client to auth layer will have different headers, but I would like to change this request to its legacy format during the journey from auth-legacy-backend-server-application and back) [easier]
I would like to add encryption (SSL) on client to auth (gateway) requests. The gateway will decrypt the request and send un-encrypted request for the auth-legacy-backend-server-application and back journey) [tougher]
A few of the legacy system requests are such that Legacy-FrontEnd (LFE) --> Legacy-Backend (LBE) use cookie based sessions. I want to use the gateway to simulate this behavior.
LFE -> gateway uses my auth mechanism (say encrypted tokens)
gateway -> LBE simulates the cookie based sessions behavior
gateway keeps the mapping of token to session-cookie
[the last point above is a over simplification of a use case we might encounter at a later date]

Related

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.

Token vs Cookie for SPA

I'm using devise_token_auth for a rails application with react on the frontend and rails as the backend acting as the backend.
In the readme the author states that
If you're building SPA or a mobile app, and you want authentication,
you need tokens, not cookies.`
Why? I understand the basic differences between tokens and cookies, but don't understand why you couldn't just use cookies (simply including the headers with any XHR requests)?
There are a few major reasons.
First of all most SPA's are designed as stateless and using cookie based authentication is not stateless. Using cookies also makes every request take a little bit longer because there is a lookup on every request.
Cookies are also tied to a domain. Most SPA's use multiple services across multiple domains which is a no go with cookie based authentication. This also applies to SPA's which have a web app and mobile app, using token based authentication means scaling this is much easier.
Tokens can also be used to store data and only need to be generated once, after that there is no work involved except for the server reading the token. This means you can store user permissions in there etc and the server can get this information with very little work.

Design pattern: ASP.NET API for RPC against a back-end application

I'm designing an API to enable remote clients to execute PowerShell scripts against a remote server.
To execute the commands effectively, the application needs to create a unique runspace for the remote client (so it can initialise the runspace with an appropriate host and command set for that client). Every time the client makes a request, the API will need to ensure the request is executed within the correct runspace.
An (over-simplified) view of the flow might look like this:
Client connects to Web API, POSTs credentials for the backend application
Web API passes these credentials through to the backend app, which uses them to create a RunSpace uniquely configured for that client
Web API and app "agree" on a linked session-runspace ID
Web API either informs client of session-runspace ID or holds it in memory
Client makes request: e.g. "GET http://myapiserver/api/backup-status/"
Web API passes request through to backend app function
Backend app returns results: e.g. "JSON {this is the current status of backup for user/client x}"
Web API passes these results through to remote client
Either timeout or logout request ends 'session' and RunSpace is disposed
(In reality, the PowerShell App might just be a custom controller/model within the Web API, or it could be an IIS snap-in or similar - I'm open to design suggestions here...).
My concern is, in order to create a unique RunSpace for each remote client, I need to give that client a unique "session" ID so the API can pass requests through to the app correctly. This feels like I'm breaking the stateless rule.
In truth, the API is still stateless, just the back-end app is not, but it does need to create a session (RunSpace) for each client and then dispose of the RunSpace after a timeout/end-session request.
QUESTIONS
Should I hack into the Authentication mechanism in ASP.NET MVC to spin-up the RunSpace?
Should I admit defeat and just hack up a session variable?
Is there a better SOA that I should consider? (Web API feels very neat and tidy for this though - particularly if I want to have web, mobile and what-have-you clients)
This feels like I'm breaking the stateless rule.
Your application is stateful - no way around it. You have to maintain a process for each client and the process has to run on one box and client always connecting to the same box. So if you have a single server, no problem. If you have multiple, you have to use sticky session so client always comes back to the same server (load balancers could do that for you).
Should I hack into the Authentication mechanism in ASP.NET MVC to
spin-up the RunSpace?
If you need authentication.
Should I admit defeat and just hack up a session variable?
No variable, just use plain in-memory session. In case more than 1 server, use sticky session as explained above.
Is there a better SOA that I should consider? (Web API feels very neat
and tidy for this though - particularly if I want to have web, mobile
and what-have-you clients)
SOA does not come into this. You have a single service.

What is the recommended Binding to use with Silveright and iPad clients

I am starting a new product that will require a .NET based server (using WCF) hosted on Azure. I would like to have basic authentication and security features. The clients are all "rich" UI but are not neccessarily microsoft ones.
We intend to have the first client application written in Silverlight, but we want to keep our options open to implement clients for iOS and Android in the future. So we do not want to use WCF specific features but rather protocols that are easily available on other enviroments.
Of course, with the Silverlight client, we hope to get as much done for us automatically as possible. We intend to only communicate through web services.
Which bindings are recommended for such a scenario?
How would you implement security? (assuming we need basic security - Users being able to log in with encrypted user and password and perhaps some built in basic role management althouh this is optional).
Suggestions?
You could use WCF to implement a REST interface
The binding would have to be a basicHttpBinding (to be open to all platforms) and using SSL to secure the line.
Managing credentials could be done using tokens to be passed back and forth after authentication. Much like a http session. You could pass the token using a cookie but the token could be part of the API or Headers as well. See this Best Practices for securing a REST API / web service
This would grant you the power of .NET and WCF without losing interopability.

Securing REST and JSON

I want to build my web services serving JSON data utilizing RESTful architecture.
But I want my own client apps only that can request from my web services.
Basically, my web services contain sensitive data that is not for public consumption, but I wanted to build it that way so I can build many different client apps that connects to my web service.
Would appreciate any ideas for this, thanks.
The fact that it's RESTful or uses JSON isn't a relevant factor when it comes to securing a web service. Any web service would need to be secured in the same manner. There are a few things you should do:
If possible, don't host your web service on the Internet. If the web service is hosted within your company's LAN, for example, it won't be exposed to public consumption unless you specifically exposed it through your router.
Set up authentication and authorization rules. If you're hosting your web service inside of a Windows domain, you could simply use Windows authentication and set up rules based on Active Directory users and groups. Other options are to use HTTP authentication, client certificate authentication, or if you're developing in .NET, forms authentication.
Use encryption (HTTPS), especially if your web site is hosted on the Internet.
You just need a couple things in place to do this. First, the service client will need to authenticate against your service (over HTTPS) to make a request. Once the client is authenticated, you can return a private token which the client has to include with this token. As long as the token expires after a reasonable amount of time, and a secure algorithm is used to generate it, this should do what you want.
If you have more strict security requirements, you can follow Jakob's suggestion, or have the client start a VPN session prior to making requests.

Resources