I'm trying to understand the concept and benefits of implementing OpenID in your project. And, since I'm a Java developer, I'm more or less equally interested in understanding its main Java implementation, openid4java.
My understanding is that OpenID is a standard for provisioning decentralized IDs in a uniform way. Now, if that is totally (or even slightly) incorrect, please correct me!
Assuming I'm still on track, I see that all sorts or organizations have been using OpenID, such as MySpace, who identifies each of their users with a URL matching http://www.myspace.com/username.
So how does OpenID work as a system? Does it just manifest itself as a network of "OpenID Servers" that, like DNS machines, coordinate and make sure all IDs in their system are unique and match a certain pattern? Or, is it just an algorithm to be used which, like GUID, produces globally-unique IDs for each client domain (such as MySpace).
I'm just not understanding how OpenID actually manifests itself, and how frameworks like openid4java ineract with that "manifestation". (What their uses are).
First, there are two sides of the OpenID communication - the provider and the consumer. The consumer is the application that tries to authenticate using OpenID, and the provider is the server to which the authentication request is sent.
Each provider has a so-called Endpoint - url that accepts authentication requests. You should know that URL in advance when supporting an OpenID provider. First you have to discover what is the endpoint for a given openId, and then exchange messages with that provider. This is all wrapped in openid4java ConsumerManager.
Then happens the authentication - you redirect the user to a provider url, where the user confirms he wants to login using his account (should be logged in), then the provider redirects back to you, and then you can get the requested information about the user (through another request)
Related
I'm using Spring Security's SAML 2.0 to connect my service provider to multiple identity providers.
Everything in Spring's SAML 2.0 documentation makes sense. I have read many helpful tutorials including this one, which are similar to my existing code.
However, I am missing where and how to select an identity provider for a given user.
I understand SAMLDiscovery can be used to delegate the identity provider selection to a third party service. I also understand how to configure multiple identity providers. But I'm looking for a way to run my own code (i.e. check a database) and then trigger a SAML request for the chosen identity provider (not a third party service). I would expect this around the time SAMLEntryPoint is hit. I have seen mention of specifying EntityID in the initial request. Is this related?
I am attempting to perform SP-initiated SAML 2.0 SSO. Can someone please point me toward where I can manually specify an IdP based on the current user?
As far as I know, SAML doesn't offer any mechanism for what you want.
SAML discovery is used to find out which IdP exist for your application.
Your problem is that you don't know who the user is before it tries to log in and when he does, it means that he already know which IdP he wants to use.
So you have these options:
Most common. Use a landing page that lets the user select which IdP to use. For example, Epic games lets you select the IdP from a list of 8. Once the user selects it, then you are good to go, by directing his request to the correct IdP.
If you know in advance which user belongs to which IdP then you can have a page that lets the user enter his username only. Once he does this, you can check in your DB to which IdP this user belongs to and send a redirect message back to the browser. While this works, it will not allow the user to select which IdP it wants to use, putting this job on the shoulders of the backend.
Do step 2 once and save a cookie in the user's browser. Then, when the user tries to log again in another session from the same machine, you can automatically redirect him to the right IdP. Using this option, everything is done automatically and except for the first time.
One thing to consider. From a security standpoint giving a hacker any info is a bad practice and so option 2,3 do reveal to a hacker which IdP belongs to which user. IMO this is not such a big breach and can be implemented.
This is not really a SAML question, since any solution would happen outside of standards and involve identifying the user before asking them to authenticate.
GENERAL PATTERN
App redirects to Service Provider using Technology A, eg SAML, OpenID Connect
For this app, the Service Provider is configured to run an action, eg present a screen, to identify the user - you may have seen this in systems such as Office365
Service Provider then uses some kind of data lookup to identify the IDPs for the next step
If there is more than one then the user is prompted to select one, otherwise the default option is invoked automatically
The Service Provider then redirects to the IDP using Technology B - could be SAML / OIDC / Other
EXTENSIBILITY
Hopefully my comments above show that an IAM system is a toolbox and should be extensible. I work at Curity where we use a concept of authenticators and actions which can be combined - eg for MFA, but a common option is as follows:
Capture the user name
Run some custom logic - eg JavaScript that invokes a data lookup to set the next authenticator
Here is a recent article to show how this works - the Username Authenticator is the interesting part.
PROVIDERS
Unfortunately Spring may not provide the options you would like. This should clarify your requirements a little though.
I am trying to build a Spray REST Web server for my mobile application on android (Eventually Iphones too). Currently, I am wondering how to determine from the server side which user is making REST Method requests. After some research I am understanding that android's SharedPreferences or an OAuth protocol can be utilized to handle user authentication. Still I am unsure how to create the entire picture of "This user is requesting some information". The message responses will be in JSON text, should the request's be in JSON as well?
I greatly appreciate all of your help, eagerly awaiting responses.
Currently, I am wondering how to determine from the server side which user is making REST Method requests.
The most adequate way to do this is to add auth layer to your server. There are many ways of how exactly you can do this, depending on security concerns you have to deal with.
Here is the list of auth schemes I would be looking into first of all:
Http basic auth (most simple one, stick with it if you can)
OpenID or OAuth (harder to implement, solves some problems that are out of scope of simply authenticating user. Note: OAuth is about authorization but can also be used to do authentication)
home-gown auth (may be implemented on different network layers, lots of options here. Do not recommend going here unless you really need to).
You can send more info from client side when user send request, you include unique info (Android ID, Ads ID for example)
server.address/request?command=abc&uid=UID...
. Another way is read IP address of the user and manage it by session.
I am currently in the early stages of creating a web application (HTML5, JS, etc.) that uses a REST API on the backend (Java, specifically Jersey v1.18). The nature of the data that will be stored is highly sensitive, so security is something that I’ve started looking at, even though the application is only in the early stages. The eventual goal will be to have native mobile applications as well, and to potentially provide access to the data for external clients via the same API.
In my research thus far, I have identified a variety of authentication methods, including HTTP Basic, token-based, session cookie, OAuth, HMAC, etc. The key component here is that the REST API will be primarily accessed by users, rather than other applications or backends. Thus, having a “login/logout” equivalent is important, and this boils down to user level authentication.
So far, HMAC authentication looks to be the most promising, as we have no plans to integrate with any OAuth provider at this moment.
I have already read through dozens of SO posts, as well as articles such as:
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
http://www.errant.me.uk/blog/2013/04/authenticating-restful-web-applications/ (note: this is clearly bad, as salting with the username is not recommended)
Ideally, HMAC seems like the way to go, but I have yet to see a recommended approach to handling the shared secret. The idea of using a resource to validate credentials, which then provides a token/nonce to be used with the HMAC scheme, seems to be an option, but I’m questioning the advantages over just using this token/nonce strictly as a token.
I know that HMAC authentication for a REST API has been discussed at length, but when used in conjunction with the authentication details that users have come to expect (username, email, password, etc.), is there any recommended approach that doesn’t require a pre-shared secret key?
This is primarily an opinion-based question, but I'll offer my two cents: just go for a session cookie.
If your primary audience is humans, and you don't need to integrate with third parties, don't bother with OAuth. Just make sure your API is only available over HTTPS, and issue a session token that the server can revoke after login. Strictly speaking it doesn't need to be a cookie; I've seen APIs that stash the token in HTML5 session storage and provide it in the Authorization header or as a query param.
If you have SSL set up properly, your users will get the expected padlock in the browser, and you'll be safe from anyone in between you and the client. If the client is compromised, you're screwed anyways. And since the client can't keep a secret, there aren't a lot of advantages to more complex HMAC schemes.
I would like to implement OAuth 2.0 authorization on my JAX-RS RESTful services.
After some researches, I've found Apache CXF to do that. However, I haven't found any examples about it and it's unclear for me. Where can I find some examples of JAX-RS with OAuth 2.0?
Disclaimer: This answer doesn't really provide a solution for securing a JAX-RS with OAuth 2.0. But it aims to give some insights to Mohasin Ali, who started a bounty on my question. Maybe, the solution I used can be useful for him.
Regarding the bounty:
The question is widely applicable to a large audience. A detailed canonical answer is required to address all the concerns.
After asking this question a while ago, I realized that OAuth 2.0 would be too complex for my requirements. Even Basic Authentication would be enough for my requirements. But I ended up using an authentication scheme based on JWT tokens signed on server side. I described my solution in this answer.
Apache CXF provides an implementation of OAuth 2.0. It may worth looking at it if you want to use OAuth for securing you API. Apache CXF also supports OAuth 1.0.
It doesn't matter the authentication method you decide to use, do it on the top of a HTTPS connection. You'll need a certificate for that. As a suggestion, have a look at Let's Encrypt. They claim to be a free, automated, and open Certificate Authority, currently sponsored by Mozilla, Akamai, Cisco, Chrome, Facebook and others.
Regarding the following situation, mentioned in the comments:
[...] a malicious user visits someone's computer, open the browser, see the access token and copies the access token to his own browser [...]
If a malicious user have physical access to a computer, HTTPS won't prevent this malicious user from stealing an authentication token from someone's computer. Actually, if it happens, I think you should have bigger concerns...
For an additional layer of security, you could consider storing the token along with the IP address of the user you issued the token for. For each request that hits your API, compare the IP of the incoming request with the IP of the user you issued the token for. If the IPs don't match, refuse the request.
If you go for JWT tokens, instead of storing the whole token, store only the JWT ID claim (jti). Just ensure this value is unique (java.util.UUID should be enough for generating the jti value).
For a completely stateless authentication (not storing the whole token neither storing token ID), you could store the IP address in a JWT token claim, but mind the token will be a few bytes longer.
Please see https://github.com/Talend/tesb-rt-se/tree/master/examples/cxf/jaxrs-oauth2 for one example, it has a collocated example (all endpoints in the same container) and more complex one with the endpoints distributed, with SAML SSO Web profile supporting SSO.
We are implementing Single Sign On [SSO] across multiple applications, which are hosted on different domains and different servers.
Now as shown in the picture, We are introducing a Authenticate Server which actually interacts with LDAP and authenticate the users. The applications, which will be used/talk to Authenticate Server are hosted across different Servers and domains.
for SSO, I can't use session variables, as there are different servers and different applications, different domains, a domain level cookie/session variable is not helpful.
I am looking a better solution which can be used for SSO across them. Any demonstrated implementation is existing? If so, please post it or point me in the right direction for this.
You can achieve this by having all your log-ins happen on the auth server. The other applications can communicate to the auth server through a back channel. The general principle is like this:
User accesses application 1.
Application 1 needs the user to sign on, so it sends a token to the auth server through the back channel. Application 1 then redirects the user to the log in page on the auth server with the token as a parameter on the request.
User logs in to auth server. Auth server sets a cookie, flags the token as authenticated and associates the user details with it. Auth server then redirects user back to application 1.
Application 1 gets request from user and calls auth server over back channel to check if the token is OK. Auth server response with user details.
Application 1 now knows that the user is authorised and has some basic user details.
Now this is where the SSO bit comes in:
User accesses application 2.
Application 2 needs the user to sign on, so it sends a token to the auth server through the back channel. Application 2 then redirects the user to the login page on the auth server with the token as a parameter on the request.
Auth server sees that there is a valid log in cookie, so it can tell that the user is already authenticated, and knows who they are. Auth server flags the token as authenticated and associates the user details with it. Auth server then redirects user back to application 2.
Application 2 gets request from user and calls auth server over back channel to check if the token is OK. Auth server response with user details.
Application 2 now knows that the user is authorised and has some basic user details.
There are some existing implementations of this method, for example CAS (Central Authentication Service). Note that CAS is supported out of the box in Spring Security. I would advise you look at using an existing implementation, as writing your own will be hard. I have simplified things in my answer and there is a lot of potential for introducing security holes if you're new to this.
I will recommend you check out OAuth. It is a good Authenticaiton and Authorization protocol used by several large organizations including facebook, google, windows live and others. It may have an initial learning curve, but it is a production grade solution.
It also has libraries for Java, Ruby, PHP and a range of other programming languages.
For example, the following server side implementations are available for Java.
Apache Amber (draft 22)
Spring Security for OAuth
Apis Authorization Server (v2-31)
Restlet Framework (draft 30)
Apache CXF
Following client side Java libraries are also available:
Apache Amber (draft 22)
Spring Social
Spring Security for OAuth
Restlet Framework (draft 30)
Please refer here for more details:
http://oauth.net/2/
http://oauth.net/documentation/
The bigger question is how you are implementing single sign on. Many open source and even proprietary (IBM Tivoli) offerings worth their salt offer cross domain single sign on capability. This would be the easiest and best way to implement cross domain sso. You can configure the LDAP server you use in the sso server you choose.
Taking for instance open sso, here is an article to configure cross domain single sign on
http://docs.oracle.com/cd/E19681-01/820-5816/aeabl/index.html
To configure LDAP in open sso,
http://docs.oracle.com/cd/E19316-01/820-3886/ghtmw/index.html
Reference on the issue is presented in a neat diagram here
http://docs.oracle.com/cd/E19575-01/820-3746/gipjl/index.html
Depending on which offering you use, you can configure cross domain single sign on.
With this, your diagram will look like this, with the auth server being your utility to interact with sso server of your choice.
Having an auth server that communicates with sso is a sound architecture principle. I would suggest making calls to authenticate as REst end points which could be called via http from different applications.
You cannot use Rest Service .
You could use what i call a Refferer Url Authentication
Say you have a Authentication application running on www.AAAA.com
In the applications , where you want to authenticate , you could have a filter which looks for a authenticated cookie in its domain else redirect to www.AAAA.com for authentication
On Successfull authentication , you could pass the user profile information as encrypted GET / POST data back to the application
Since I have built a Java application, I have been looking for an SSO solution for it. I found a free Java SAML Connector using which you can achieve SSO in java based applications built using any java framework.
Here's the link to it - https://plugins.miniorange.com/java-single-sign-on-sso-connector