Cross Platform Login - authentication

I am working on an application where all user authentication happens in a ColdFusion application (based on CFWheels), but interactions with the file servers happen through a Node.js application. I need to make sure that the user who is logged in on the CF application is allowed to access the files in the node server. I was thinking of setting a cookie with a CFToken or something that the node server can read and pass to ColdFusion asking "Hey can this token access this file"
My only problem with that is I wasn't sure if CFTokens are re-used eventually, and if they are what should I use instead?
If other people have other ways of doing this sort of thing where authentication needs to be reusable across multiple engines I would love to hear your strategies.

That sounds like a fine way to do it.
But, I would just use CFCOOKIE to set a cookie of your own devising.
The two servers will have to share a domain name, of course, to be able to read the same cookie. You will also have to set the cookie to be a domain cookie.
One clean way to architect this would be to create a whole CFC devoted to the security.
It would have methods for generating and validating login tokens.
Your CF application would use this to generate the token, and you could have your node.js application call this via a webservice using the
http://server.com/path/security.cfc?method=validateToken&token=whatever
An even more efficient way to do this, assuming they have access to the same datastore, would be to use the same algorithm to generate/decode (if needed) the tokens in both systems, and let the node.js app directly access the datastore.
When I needed to do this, we stored the "session" tokens in mongodb, and directly accessed the datastore from each application (CF, Java, and Rails). The CF system was responsible for the initial authentication. The other two systems did no authentication, just validated the token, and if it was not found/invalid/etc, responded in the appropriate way.

Yip, what you want to read up on is SSO (Single Sign-on).
OpenID is a popular one that works with multiple platforms including CF.
If you're feeling adventurous... With a little tought, it is fairly easy to devise your own mechanism for sharing logins - usually around sharing some token via a cookie or header or could also be via RESTfull (or any) form of webservice call too.

Related

Does it make sense to use OAuth for a native desktop app that owns the resources it uses?

We have a native Windows desktop app that uses resources that we control on behalf of our customers. In the vein of not rolling our security infrastructure I am wondering if it makes sense to use an OAuth library / framework like IdentityServer (our frontend and backend stacks are .NET based with ASP.NET Core on the backend).
But from what I have read OAuth is all about giving an application access to resources that the users owns that are managed and controlled by another party without exposing the user's security credentials to the application.
Given the application is from our point of view "trusted" it seems more straight forward for the application to capture the password directly from the user and obtain an access token (e.g. bearer token) from directly from the back end rather then redirecting the user to the web browser.
Management of authorization levels for various resources is something we need to take care of robustly, as we will have multiple applications and users which will need configurable access levels to different types of resources, so I don't really want to be rolling our own solution for this.
We also want the ability for users to remain logged for indefinite periods of time but to be able to revoke their access via a configuration change on the back end.
Should we be using a different type of framework to help ensure our implementation is sound from a security point of view? If so please any suggestions of suitable technology options would be most helpful.
Alternatively, is there a OAuth flow that makes sense in this case?
It sounds like the "Resource Owner Password Credentials Grant" might help with your problem.
In the short term, the use of oauth may not seem very different from the normally "username password + rbac" based model, but the benefits may come in terms of scalability later on, for example when single sign-on needs to be implemented, or when it comes to the need to provide service interfaces to third parties.

Microservices - how to solve security and user authentication?

There is a lot of discussion about microservice architecture. What I am missing - or maybe what I did not yet understand is, how to solve the issue of security and user authentication?
For example: I develop a microservice which provides a Rest Service interface to a workflow engine. The engine is based on JEE and runs on application servers like GlassFish or Wildfly.
One of the core concepts of the workflow engine is, that each call is user centric. This means depending of the role and access level of the current user, the workflow engine produces individual results (e.g. a user-centric tasklist or processing an open task which depends on the users role in the process).
In my eyes, thus a service is not accessible from everywhere. For example if someone plans to implement a modern Ajax based JavaScript application which should use the workflow microservice there are two problems:
1) to avoid the cross-scripting problem from JavaScript/Ajax the JavaScript Web application needs to be deployed under the same domain as the microservice runs
2) if the microservice forces a user authentication (which is the case in my scenario) the application need to provide a transparent authentication mechanism.
The situation becomes more complex if the client need to access more than one user-centric microservices forcing user authentication.
I always end up with an architecture where all services and the client application running on the same application server under the same domain.
How can these problems be solved? What is the best practice for such an architecture?
Short answer: check OAUTH, and manage caches of credentials in each microservice that needs to access other microservices. By "manage" I mean, be careful with security. Specially, mind who can access those credentials and let the network topology be your friend. Create a DMZ layer and other internal layers reflecting the dependency graph of your microservices.
Long answer, keep reading. Your question is a good one because there is no simple silver bullet to do what you need although your problem is quite recurrent.
As with everything related with microservices that I saw so far, nothing is really new. Whenever you need to have a distributed system doing things on behalf of a certain user, you need distributed credentials to enable such solution. This is true since mainframe times. There is no way to violate that.
Auto SSH is, in a sense, such a thing. Perhaps it may sound like a glorified way to describe something simple, but in the end, it enables processes in one machine to use services in another machine.
In the Grid world, the Globus Toolkit, for instance, bases its distributed security using the following:
X.509 certificates;
MyProxy - manages a repository of credentials and helps you define a chain of certificate authorities up to finding the root one, which should be trusted by default;
An extension of OpenSSH, which is the de facto standard SSH implementation for Linux distributions.
OAUTH is perhaps what you need. It is a way provide authorization with extra restrictions. For instance, imagine that a certain user has read and write permission on a certain service. When you issue an OAUTH authorization you do not necessarily give full user powers to the third party. You may only give read access.
CORS, mentioned in another answer, is useful when the end client (typically a web browser) needs single-sign-on across web sites. But it seems that your problem is closer to a cluster in which you have many microservices that are managed by you. Nevertheless, you can take advantage of solutions developed by the Grid field to ensure security in a cluster distributed across sites (for high availability reasons, for instance).
Complete security is something unattainable. So all this is of no use if credentials are valid forever or if you do not take enough care to keep them secret to whatever received them. For such purpose, I would recommend partitioning your network using layers. Each layer with a different degree of secrecy and exposure to the outside world.
If you do not want the burden to have the required infrastructure to allow for OAUTH, you can either use basic HTTP or create your own tokens.
When using basic HTTP authentication, the client needs to send credentials on each request, therefore eliminating the need to keep session state on the server side for the purpose of authorization.
If you want to create your own mechanism, then change your login requests such that a token is returned as the response to a successful login. Subsequent requests having the same token will act as the basic HTTP authentication with the advantage that this takes place at the application level (in contrast with the framework or app server level in basic HTTP authentication).
Your question is about two independent issues.
Making your service accessible from another origin is easily solved by implementing CORS. For non-browser clients, cross-origin is not an issue at all.
The second problem about service authentication is typically solved using token based authentication.
Any caller of one of your microservices would get an access token from the authorization server or STS for that specific service.
Your client authenticates with the authorization server or STS either through an established session (cookies) or by sending a valid token along with the request.

Web API authentication/authorization using SSO instead of OAUTH - will it work?

Updated based on questions from #user18044 below
If a user is authenticated in two different web applications via 2 different SAML-based identity providers, and one of the applications needs to request data from a web API exposed by the other application, would it be possible to call the web API methods securely by virtue of the user's current authenticated status in both applications without separately securing the API methods via an API level authentication protocol such as OAUTH? Note that both applications are owned and operated by my company and share the same 2nd level domains and user base, even though the identity servers are different (one is legacy).
Some further information: Application A is a portal application that is going to host widgets using data supplied from Application B. Application A will only communicate with application B via a web API exposed by application B. Currently application B does not expose a web API (except internally to the application itself). This is new functionality that will need to be added to application B. Application A will use Okta as its SSO. Our lead architect's proposal is to continue to use a custom legacy IDP server that we developed internally based around using the dk.nita.saml20 DLL. They are both SAML based I believe, but I don't think they could share the same identity token without some retrofitting. But this is hitting the limits of my knowledge on the topic of authentication. :) I think our architect's plan was to have the user authenticate separately using the two different identity providers and then only secure the web API using CORS, his reasoning being that since the user is already known and authenticated to use application B, that there wouldn't be any security implications in allowing application A to call application B's web api methods, as the user should be authenticated in application B. This seems quirky to me, in that I can imagine a lot of browser redirects happening that might not be transparent to the user, but other than that, I'm just trying to figure out where the security holes might lie, because it feels to me that there would be some.
I know that this approach would not be considered a best practice, however with that being said, I really want to understand why not. Are there security implications? Would it even work? And if so, are there any "gotchas" or things to consider during implementation?
To reiterate, our lead architect is proposing this solution, and it is failing my gut check, but I don't know enough on the topic to be able to justify my position or else to feel comfortable enough to accept his. Hoping some security experts out there could enlighten me.
It's hard to answer without knowing more on how your current applications and APIs are secured exactly. Do the web application and its API have the same relying party identifier (i.e. can the same token be used to authenticate against both)?
If both web applications use the WS-Federation protocol to authenticate users, then most likely the SAML token will be stored in cookies that were set when the identity provider posted the token back to the application.
You do not have access to these cookies from JavaScript. If the web API that belongs to application B uses the same cookie based authentication mechanism, you could use this provided you allow for cross origin resource sharing.
If your web API uses something like a bearer token authentication scheme (like OAuth) or has a different relying party id in the STS, this would obviously not work.
I think the reason this fails your gut check is because you are basically accessing the web API in a way a cross-site request forgery attack would do it.
A problem I see with this approach is that if the user is not authenticated with the other web application, then the call to your API will also fail.
I agree with user18044 as far as it being based on a cross-site request forgery attack and the security between applications. Is it true that if User X has access to App A, that they will have access to App B and vice versa? If that is not the case, then each application will need to be authenticated separately...and it won't be a SSO. I found these links that might be helpful in your situation.
https://stackoverflow.com/questions/5583460/how-to-implement-secure-single-sign-on-across-various-web-apps
https://developer.salesforce.com/page/Implementing_Single_Sign-On_Across_Multiple_Organizations

Token authentication with rest backend secure enough

I would like to secure my mobile app ( hybrid app, build with ionic framework). On backend site I use the play framework. I would implement the following case. The user of the app should authenticate to rest backend by email and password, if the credentials correct the backend generates an token return ok with the generate token to client, otherwise the backend return bad request. If the user would try to login with incorrect credentials more then 10 times the user would deactivated for 1 hour.
The mobile app would load json data from backend with ajax calls, on each call in header would set the field 'X-AUTH-TOKEN' and the generate token. The backend check the token and if the token is correct the client get data from server with status ok else the client get none data and the status unauthorized. If the user logged out the token would destroyed on server and client side. The token would not change as long as the user is logged in, in worst case the token would not changed over more than many days. I could implement, that on each call the date of last call can saved and if the last call is more than x days in past the server return unauthorized and destroy the token. So the user should logged in. Is the case secure enough, or should I implement more logic?
What you are describing is very similar, if not identical to the many, many implementations of OAuth2. For more information on these types of flows, including diagrams, check out how Google describes their OAuth2 processes here: https://developers.google.com/accounts/docs/OAuth2
I'm not familiar with the play framework but you should speak with framework experts to see if there is a well-tested, battle-hardened oauth2 implementation out there for the Play Framework. If so, you want to use that. You really don't want to (and shouldn't) roll your own implementation unless you know what you're doing and are willing to pay for people to pentest it. Really, please don't do this if unsure.
On the Ionic Framework / Angular / Cordova side, you've basically got it correct, but should always consider some basic security considerations:
My guess is that you'd use local storage to store the access token. In REST we don't have sessions like in a traditional web server scenario so we use the token in lieu of the session. Of course the downside is that local storage can easily be inspected to obtain the access key if someone had either root access on the device and was able to work their way into the app sandbox and knew exactly what api key to grab from local storage, but if someone has root or physical access to the device then you've got a bigger problem, so this isn't a design flaw per-say. To a certain extent, using this method you're relying upon the OS/browser's local storage sandbox to prevent other apps from accessing the local storage in your ionic app. This is a bet I would be willing to make, but you'll need to judge that based on your security vs usability needs.
What you should really be focusing on is protecting the token from people who may be listening on the wire (think coffee shop wifi). This means setting up your auth rest servers to use exclusively HTTPS (don't fail back to HTTP). This may have downsides, but will be worth it to protect your user's data. You also correctly identified using the token header. You should never pass auth tokens in anything but the header or POST data.
Generally speaking, what you are describing should be safe for use in a consumer level app. This assumes you don't unwittingly use any malicious third party code in your app. As always, you should be especially wary of third party code and only use code that you absolutely trust. Any code run from inside your app can access local storage in the Cordova/browser local storage sandbox and could theoretically export the api token for use in other software to access your api. With that said, you asked about authentication and not authorization. Keep in mind that your users need to only have access to do certain things in the app based on user-roles or some sort of ACL. This authorization outside the scope of this answer but you need to ensure that this is done on the server side and has rate limiting or soft-deletes for shared resources to prevent a malicious user from deleting everything.
Good luck with ionic and have fun.

Implementing "true" Single Sign-On: OpenID, something else, or custom hack?

We're trying to evaluate a solution to implement "true" SSO for multiple (already existing) web solutions. True SSO here means to login on any service, and be authenticated on all, without further actions from the user.
All of the applications we're going to use support OpenID and/or have plugins that allow OpenID, so this seems like something worth looking into. However, as I understand OpenID, the users would still be required to enter their OpenID credentials in each service.
Is there a sane way to implement SSO with automatic login once the OpenID provider has authenticated the user?
In an earlier project, we hacked up the PHP session data in the login procedures of two applications (both running on the same domain and server) so a login in the first application creates the session data for the other application as well. However, this is a very hacky solution and is prone to break when either application is updated, so we're trying to avoid it this time.
Are there any other SSO solutions that we could look into?
i am assuming that you have the control on the SSO implementation
there are some things you can do to make sure that once the user has been recognized by the SSO application, he will virtually automatically be logged in to your other applications
in your SSO application, create a whitelist of service providers. authentication request from those websites will be automatically approved. thus, user won't be asked to approve the request manually
in your application, set the return_to parameter as the page the user is intending to immediately open. don't simply set the return_to to that application homepage
by the way, the most standard openid implementation accepts any url. however, if you want to use the sso in a controlled environment, you can set the service provider to have a whitelist of trusted identity providers. after all, it's the service provider which initiated openid authentication.
Yes, there is a means to do this. Run an Application Server, Node Based, and register cross-domain techniques to offer cookie-credentialed (backed up by site-handshakes as each new user arrives, to scale better and minimize resource expenditure per-session).
I am working on such a beast right now, and I'm 5/6th done.
I have taken care of several annoying variables up front- including the means to assure unique user logon- and I've taken a stand on other issues- one just can't get everything done in one system. However, one can have a true SSO if one is willing to pull out some stops. It is YOUR stops which will define your solution. If you have not accurately portrayed your limitations then there isn't a solution which can be offered for implementation here, and the nature of your problem is ENTIRELY implementation- not theory. In theory you have 4-5 different options. In practice you will find your answers.