We are developing an SSO application using IdentityServer4 as the authentication (not authorization) infrastructure for other (client) websites in our company. One of our main concerns is the failure of the SSO website. In this situation, what considerations should we consider to minimize clients issues?
For example, we want to create a local login page in each application and ask each application to authenticate it using the OTP mechanism. Is this enough or are there better solutions?
For security reasons, you should not try to add some local login, it will just make things more complicated, complex and probably less secure.
Because your tokens have certain lifetime (like 1 hour default and if your SSO goes down for a short while, then you clients can continue to operate (unless you query your SSO all the time).
If you want to make it more reliable, then you need to start looking at load-balancers and having multiple instances running of IdentityServer. That can work if you do take care to have the same keys on all the instances.
Related
Am teacher and I make and sell Question bank (qbnak) for many standardize test.
I've built a business using two different service, in which both requires sign-up, So If i had a customer he should create two account one for the first service and another for the second in order to get to qbank each time
The first service is Teachable and the second is Speedexam .
So my Questions is:
How to automate user signup rather than doing it manually?
What is the permanent solution for this, What do you call it SSO/oAuth or API ?
And what are my options if SSO and API are not support in both services?
Thank you
Like you mentioned, what you're trying to achieve is generally referred to as SSO.
Single Sign On works by having a central server, which all the applications trust. When you login for the first time a cookie gets created on this central server. Then, whenever you try to access a second application, you get redirected to the central server, if you already have a cookie there, you will get redirected directly to the app with a token, without login prompts, which means you’re already logged in.
(source: How to Implement Single Sign On)
You have a few options on how to implement this:
Create your own authentication server and define your own processes around how the other application interact and perform authentication
⤷ (not recommend, time consuming and easy to get something wrong)
Create your own authentication server compliant with available authentication standards like OpenID Connect and OAuth 2.0
⤷ (time consuming and complex, but at least you're following standards so less likely to really mess up)
Delegate the authentication to a third-party authentication provider like Auth0
⤷ (easy to get started, depending on amount of usage it will cost you money instead of time)
Disclosure: Answer provider by an Auth0 employee.
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.
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.
My company is re-writing its e-commerce site as a single page application using the new Web API / SPA features in MVC 4. We're not sure about the best way how to handle authentication.
Specific questions:
How do we handle both encrypted and non-encrypted communication? Clearly, we need to use HTTPS for the login, account, and checkout AJAX, but we'd like to use HTTP for browsing the catalog in order to avoid expensive SSL handshakes that would slow the whole site down. Is this even possible for a SPA, or are we stuck with HTTPS for everything?
What sort of authentication should we use? Primarily our site will be accessed from a web browser, so cookies may be fine. But down the road, we may want to make a custom iPhone app. Is Basic Authentication, OpenId, or OAUTH preferable? If so, why?
If we go with Forms Auth and cookies, will the redirect issue be fixed for the release of MVC 4, or do I have to use the haack?
If we go with Basic Authentication, how do you do persistent sessions, so that users don't have to log in every time they go to the page again.
Which authentication methods are well supported by ASP.NET MVC 4. It'd be ideal not to have to write a lot of specialized code.
Thanks in advance
1. How do we handle both encrypted and non-encrypted communication? Are we stuck with one protocol, https, with a spa?
You are not stuck with one protocol. With a spa you can use ajax to communicate over http or https, whichever one you choose at any given time. I would use https for anytime your are sending sensitive information like a persons name or their birthdate or login credentials.
Once a user logins to your site over https then your server can set a forms authentication cookie for that user. This cookie should be an encrypted value that ties their session to the server. You must be aware that if the rest of your site is using http then you have the risk of this cookie being passed over the wire in plain text. Even though the contents of the cookie can be encrypted, using an encryption algorithm of your choosing, a malicious person can steal this cookie and jack your user's session.
This might not be a big deal to you though if they are only allowed to browse the site and create a shopping cart. Once the user is ready to checkout then you should re-authenticate the user, over https, as a sort of double check to make sure they are not a malicious user. Amazon does this.
2. What sort of authentication should we use?
Well, that's all a matter of what features do you want your site to have.
OAuth is for exposing webservices which you can allow other sites to call with delegated access. What this means is that if you have a user who wants another site (site x) to be able to access features on your site for their profile. The site x can redirect the user to an oauth endpoint on your site which will authenticate the user. Your oauth endpoint will ask the user if its okay that certain features are shared with site x and if the user agrees a token will be generated. The user passes this token to site x where site x will make server to server calls to your site. Site x will present the token in the calls so the calls to your services will be a delegated access call. OAuth is a way of provisioning other sites to make delegated access to your services. I hope i was able to explain that clearly.. I'm not always good at this.
OpenID is not a very secure way of handling authentication its more of a convenience so that users don't have to be hassled with registering an account with your site. Because OpenID is completely open you are trusting another provider to validate your users. If the third party provider's user store is compromised then your users are compromised also. It's an example of a voucher system where you are basically saying I will trust who you say you are, if you can have an OpenID provider vouch for you.
Another solution is WS-Federation. WS-Federation is if you have multiple sites and you want to have 1 authentication provider that you trust. This authentication provider can be yours and basically all your sites say if you want access to my site then you have to first be authenticated with my authentication provider. This authentication provider can live on a seperate domain and can choose any authentication mechanism it chooses. You are trusting that this auth provider will do its best job to manage your users accounts.
WS-Federation can be overkill though if you only want authentication on your site and don't have multiple sites. In that case I would just recommend doing Forms Authentication and this should be simple enough to do. There are lots of examples of how to do this and microsoft provides many solutions for how to do this. You should look into creating a custom membership provider.
Once a user has been authenticated with your site you should create a forms authentication cookie. This cookie ties the user to their session on the server. This applies to all the scenarios listed above. MVC 4 supports all the scenarios listed above also.
Thanks, and feel free to ask more questions if I wasn't clear enough.
** EDIT 12/1/2017 **
Coming back to this question years later I have learned that relying on cookies for REST based APIs is not a good idea. You don't want to create a session on your web application because it makes your app harder to scale. So, if you need authentication then use HTTPS with some form of authentication (BASIC, DIGEST, Token Based, etc..). So, your SPA client appl will set the Authorization header on every http request and then your web server app will re-authenticate every request.
The main downside of using ASP.NET's form based security is that it assumes you're want a 401 web page when your authentication fails (useless when you're doing an AJAX call) and it's really designed around doing redirects which kind breaks the whole SPA pattern. You can hack around it but it's not designed for the purpose you're using it.
This toolkit may provide an alternative to ASP.NET'as form model.
Not yet sure how mature it is ...
http://www.fluentsecurity.net
Feedback welcome.
I just started working with webapi myself so don't consider my answer authorative. I'm not a security expert though I should be. I ran into the same questions as you did and found, as you did, that there is no authorative answer though - within mvc webapi at any rate. Looking at other webapi specs may give you some inspiration.
The simplest way I came across was of course using SSL. That let's you get away with sending credentials in clear text in the header. Doesn't break rest.
My api will employ SSL all the way but I wanted to double up anyway. So I'm sending an encrypted key in the querystring for all my requests. Pretty much the way cookieless authentication works for a non api asp site, but mvc doesn't play with it so I've rolled my own solution.
On a mobile site, the user would log in, be redirected, to the app with the encrypted key encoded into the js. So he'll initially have a cookiebased auth for the site, and be responsible for it's protection, password saving etc.
Another api consumer would get a more permanent "secret" from a dev site yet to be made and use that to check out a key.
Normally mvc authentication is stateless, meaning the ticket is never invalidated server side. If you controll the client you can just ignore invalidate cookie requests if the server logs you out, and just keep on reusing the ticket. Eventuelly you might want to keep track of your tickets server side, but it's not stateless, doubt if it's restfull, and by consequence scalability taket a hit. But authentication is pretty important so...
I need to build a scalable single sign-on mechanism for multiple sites. Scenario:
Central web application to register/manage account (Server in Europe)
Several web applications that need to authenticate against my user database (Servers in US/Europe/Pacific region)
I am using MySQL as database backend. The options I came up with are either replicating the user database across all servers (data security?) or allowing the servers to directly connect to my MySQL instance by explicitly allowing connections from their IPs in my.cnf (high load? single point of failure?).
What would be the best way to provide a scalable and low-latency single sign-on for all web applications? In terms of data security would it be a good idea to replicate the user database across all web applications?
Note: All web applications provide an API which users can use to embed widgets into their own websites. These widgets work through a token auth mechanism which will again need to authenticate against my user database.
I would not integrate the authentication on the database level, as in replicating the db or allowing access from the other servers. This might become hard to maintain. I would prefer a loosely coupled approach by exposing a simple service on your central server that lets the other app servers run authentication requests.
You should look into the following issues (probably more):
How to avoid cleartext transmission of passwords between servers
You probably can't throttle the service if a network of application servers authenticates all their users from the same IP, so you might want to restrict access to certain clients to avoid rogue machines mass-probing for valid accounts.
How to centrally enforce things such as session expiration
How to handle / avoid service downtime
Techniques that might be helpful:
Cryptographic CRAM (to avoid password transmission)
Certificates (to prove the clients' identity)
Alternatively, you might want to have the clients use the central service to obtain a token that is then promoted to and verified by the target server. There's architectures that work similarly (e. g. Kerberos ticket servers) which may serve as inspiration.
You should go for Oauth2 or SAML.