Rails Single-Sign on service and communicate to a REST API - ruby-on-rails

At my company we are developing several web applications that uses a REST API server.
First a little introduction.
The app provides the ability to manage users through the REST API and allows the users to login to the app.
Right now the REST API is for internal use only because we plan to develop more apps and communicate to the REST API as the central point of data access. We are handling the REST API authentication with a "Resource Owner Password Credentials Grant" implementation for the internal apps.
What we need is a Single-Sign on service for all the apps, we want a user to login to an app and if he/she access to another of our apps he/she will be already loged in.
We have been experimenting with the CAS protocol, with the CASino library specifically and it works great.
The problem is we don't know how to handle the flow between the apps, the REST API and the SSO service, also I don't know if there is a better choice regarding SSO services.
My questions are...
How we could handle the flow between the apps, the REST API and the
SSO service, because the REST API should be stateless it should not
communicate to the SSO service? or is there a way to communicate the
REST API to the SSO service?
Is there a better choice to implement a Single-Sign on service,
maybe OAth or OpenID and are this options suitable for REST APIs?
Thanks in advance!

Your REST API will have to talk to the SSO server to validate the Access Token, unless all the information it needs is encrypted inside the Access Token. Not sure what you mean by "flow between the apps", you should have all apps talking to a central SSO server.
When a user wants to create an account on WebApp1, the account should be created on the SSO server, either by redirecting them there or if you need a differently styled signup form for each web app, then via an AJAX call to the SSO server's REST API. I would recommend the latter as redirecting is more difficult to debug and it can make a bad user experience.
Make sure the messaging is clear, i.e. not "Sign up for a WebApp1 account", but "Sign up for a MyCompany account to get access to WebApp1".
OAuth 2.0 is very popular and people have more experience with it, so it's easier to get help or integrate with apps created by others.
The doorkeeper gem is a good server library.
OAuth 2.0 is normally used when the SSO server doesn't trust the client apps (e.g. Facebook, Twitter), but it can be implemented in such a way to skip the client authorization step (where the user is asked to approve the client app), and you can use the Resource Owner Password Credentials Grant via a REST API.
CAS is easier than OAuth. It is fairly easy to implement the basic endpoints and that way you can customize it as you wish.
I worked on a CAS-based server with a custom implementation (not sure if it was even really CAS-compliant). The authentication was done with Devise (I don't recommend Devise if you're going to customise it a lot, make your own in this case). The original flow was that the user went to the website, clicked Login/Register and then was redirected to the SSO server and after the user logged in, redirected back with a one-time ticket that the website's backend exchanged to an access token via a REST API call.
Then we added a REST API that was called from each website with AJAX. You send the username/password/captcha/etc and get back an auth token, which the site sends to its own backend. The SSO REST API can also set a cookie on its own domain, so that if the user visit another of our web apps it makes a call on pageload to check if the user is logged in. This way you're automatically logged in on every webapp without the redirect mess.
All tokens issued + the associated user info were sent to a fast Node.js app that would save them to Redis, and the app backends would call this app to validate the access tokens really fast, without putting load to the SSO Rails app.

Related

(How) does one secure a Web API with OpenID Connect (or not?)

Is it recommended or good practice to protect a Web API directly with Open ID Connect or not?
The setup:
Mobile App
Authorization Server (ADFS 4.0)
Web API (ASP.NET Core)
Currently I do the normal OAuth2 "Authorization Code Flow", and then pass the access_code to my Web API in the HTTP Header as "Authorization: Bearer ".
In ASP.NET core I just do the usual
services.AddAuthentication(...).AddJwtBearer(...)
Works fine.
But everyone talks about OAuth2 beeing only "pseudo-authentication" with certain flaws. I want my Users to be a properly authenticated before using my Web API. So it seems like Open ID Connect should be the way to go, aka "real authentication".
But does it actually work to "consume" Open ID Connect authentication in an ASP.NET Core Web API? And if yes, how? And is it good practice? All samples seem to be about Web Sites, not Web APIs.
There is an extension method
services.AddAuthentication(...).AddOpenIdConnect()
But here Implement OpenID connect Authetication in asp.net WEB API they state that "this component is designed for user interactive clients".
What i also don't understand, what would I do with the "id_token" I get from Open ID connect.
Currently i just pass the "access_token" as Bearer.
How do i consume the id_token?
Some clarifications:
The API does not act on behalf of a user (access to company data).
The API already has access to the "data". It does not require any auth workflows for itself nor does it need to pass the users credentials along.
The API needs to know "WHO" the user is, and it has to be done in an modern and good way
That's why I was thinking of OICD with its "real auth" (VS Oauth2-only which is "pseudo").
I basically cannot wrap my head around how the stuff returned from OICD (id_token) will be passed to my Web API.
OIDC is an OAuth workflow. It merely extends OAuth; it is not a replacement for it. APIs are typically authorized either by token or client secret. The difference is simply whether it's acting on behalf of a specific user or not. For example, something like the Facebook API has both workflows for its API, you generally operate with Facebook's API as a client app using the app id and client secret for your app, or you can do user-specific things like create a post on the user's wall given an authorization token.
That authorization token almost invariably comes from an OAuth workflow. Given your stated setup, your mobile app would handle this to get an auth token for the user from your ADFS server. Your API, meanwhile, would actually probably do both. It would communicate both using an assigned client secret and a user auth token, if the mobile app provides it with one.

Guide for implementing oAuth2 authenticated calls to an api

I have developer an API that is secured by oAuth2 and Azure B2C. I now want to access that API from a legacy web forms application which is using Forms as it's authentication mechanism.
I have used hellojs successfully on the client side to trigger the authentication method in a separate browser window and then use the access token successfully to call my API but how do i do this from the server side?
All the examples I've seen when setting up oAuth2 involve securing an API using the OWIN middleware (e.g. with Facebook login, etc) but I need to retain the existing forms authentication and simply invoke code that calls the API and handles the access code/token etc.
If I need the backend system to make requests on behalf of a user, should I be storing the access token securely somewhere?
The simplest approach would be to have the users authenticate against B2C separately. Think of this in terms of "linking" their account in your Web Forms app to their B2C account. If you also request the offline_access from Azure B2C, you'll receive a Refresh Token that you can exchange for a valid Access Token when needed.
Ideally, you should pivot away from Forms authentication. It's a very outdated model. It may, however, be a non-trivial amount of work which is why many folks often choose to start with the "linking" strategy and only tackle Forms Auth when they're doing a larger refactoring of their app.

Thinktecture single sign out

I am working on a AngularJS web app and I am trying to implement single sign on. I had a nice implementation using Identity server and authorization server with implicit flow and oAuth tokens, however I need a mechanism to sign the user out of all apps they are signed into.
I am currently redirecting the user to authorization server, this then redirects the user to identity server. The user logs on and it shown a consent screen, a Json web token is then sent to the app via the query string and is put into local storage. This token is attached to the Authorization header which the web api (that is on a different domain) receives and either allows or denies the request.
The problem is oAuth has no way of singing a user out of all apps. I have now looked at WS-Federation using Json web tokens but this approach still appears to use cookies which I would like to avoid as the api and client app are on different domains.
Does Thinktecture Identity Server have any way to do this and if so are there any examples I could take a look at.
Thanks
As you already said - OAuth2 is not an authentication protocol and hence does not have the concept of (single) signout.

Implementing a login system for web apps and web API with DotNetOpenAuth

I'm looking for some guidance on what people think are the best set of technologies to use. We are looking to create a web portal to allow customers to register/login with standard credentials or their social accounts (Google, Twitter etc).
Once they are registered and logged in to the portal they can access our different web apps which will know who they are and what permissions they have based on a token. We will also need to secure a set of web APIs using some sort of OAuth mechanism, so the user would possibly create an account on the web app and then create an application which would give them the keys they need to access the API from their own app.
We have a basic portal app using MVC 4 and DotNetOpenAuth which allows a user to create an account and login with either a username and password or their Google, Facebook account etc.
The APIs would be MVC 4 Web APIs
Ideally the whole set up needs to be as simple as possible, I've briefly looked into using Windows Azure Access Control (ACS) as a way to cut out some of the heavy lifting but its hard to tell where exactly it all fits together.
Currently we run an ADFS 2.0 server and WIF to allow web login to our apps but it doesn't seem like it would be an ideal choice when integrating the social login and for securing the web APIs
I guess it could be two quite seperate parts, once they are logged into the portal, how would we go about providing some sort of claims token to the other apps they then access to understand who the user is and what they are allowed to do. And maybe the web API authentication/authorisation is its own entity?
Thanks for your time
We ended up using the built in MVC 4 login system and also added JWT token support, when a user is logged in a JWT token containing their claims is stored as a cookie. This is then automatically passed around our sites on the same domain by the browser, when the web API is called from javascript it checks for the token in the headers sent by the browser and either validates it and returns the correct data or returns an unauthorised response.
It doesn't cover all the bases, we can't give trusted third parties access to our web services yet

Twitter update access with OAuth and DotNetOpenAuth

I'm trying to use OAuth with .NET (DotNetOpenAuth) to send updates to a Twitter account via a web application. I understand the basic workflow of OAuth and Twitter.
Where I'm confused if is it useful in a server web application? I don't want any user interaction.
But how it seems after an application start, the request token needs to be recreated and also an access token. This involves user interaction.
What is the correct workflow for my case?
Storing the request token or access token in config file?
Or the easist way, using HTTP basic authentication?
Thanks
If I understand you correctly your application will not be interacting with Twitter on behalf of your users but will be acting as the Twitter account for your application.
In this case there are 2 main factors to consider.
1) Do you want "from API" attached to each status as will be if you use basic auth or your applications name will happen if you use OAuth.
2) Do you want to put in the extra effort to implement OAuth.
If you decide to go with OAuth you would store your apps consumer key/secret and the accounts access token in configuration just like you would store the accounts screenname/password.
Your "request token needs to be recreated" phrase suggests you might be running into the problem where every time your user visits you need to re-authorize to Twitter, and perhaps you're looking for a way to access the user's Twitter account while he's not at your web site, and how can you do this when their token isn't fresh from being re-authorized. Is that right?
If so, the user isn't supposed to have to re-authorize Twitter every time they visit your site. The token is supposed to last a long time, which would also allow your site to access their Twitter account when they are not directly interacting with your web site. The problem may be that you haven't implemented the IConsumerTokenManager interface, but are instead using the default InMemoryTokenManager, which is for sample use only, since this memory-only token manager loses tokens every time the web app is restarted. Your own implementation of this simple interface should store and read the tokens out of some persistent storage such as a database.

Resources