I want to implement a token-based authentication mechanism for a scenario which is similar to the following:
In Google Calendar, you can invite guests to your event, who in turn can respond to these events right from the email invitation. The invitation to such an event contains the respective links to respond (Yes, No, Maybe) with authentication tokens encoded in the URL. These authentication tokens are restricted to the specific event and user.
What's the best practice to generate these kinds of "one-time" tokens that can only perform limited actions and have only access to limited resources (and potentially are only valid for a limited amount of time)? And how do I implement this in Glassfish? I want to expose this through the RESTful API of my application (using Jersey). Currently, all URL paths in my app are secured with an authentication constraint, which I configured in the web.xml.
My approach to this would be as follows:
Provide a URL where no authentication constraint is applied (e.g. /token_auth) and use this for token authentication.
In the web service method, manually check the security tokens and do the required actions. The tokens are saved in the DB along with information such as username, expiration date, authorized resources, etc.
I was wondering whether there is a more elegant solution using any frameworks or built-in container capabilities that can avoid all the manual work. And whether this solution might have some security drawbacks.
A similar question has been asked on SO before: Newbie at JAAS authentication; Sign in using a token in the URL Bar
Have you looked into UUIDs?
At work we use the Safehaus UUID.
You approach looks fine. I am not aware of a framework to do this kind of thing for you. Spring Security may have something you can use but not the whole thing.
Related
I am searching for the best approach of authenticating users of mobile clients when accessing my RESTful API. For example, how approximately AirBnb uses it's auth module.
Should the authentication be different for RESTful and basic session-based resource, working with the same data?
I am not a mobile developer therefore, I am interested in what is the best way to provide authentication from server-side, so the mobile-platform developers could use it simply.
I googled for few approaches using OAuth, OAuth2, HTTPBasic authentication and still wonder how the mobile developers can use such API, how they will store this token (cookie is stored by browser in browser-oriented apps).
Could you please suggest me some links/code samples/techiques that you used in production or pet-projects or something?
An easy and manageable alternative to OAuth(2) for authentication is JWT.
You don't need additional infrastructure, the workflow and use is straightforward and there are ready to use libraries for all major languages already available.
Compared to HTTP Basic Authentication JWT is more flexible by transmitting additional information not just credentials, you can store the JWT token as JSON or you can use cookies, you don't need to store the credentials on client side and you don't transmit the credentials on every request.
Also based on JWT you can realize very easy a single sign on function. So if you need more than just a simple system user then you should definitely try JWT.
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 want to have authorization in my Java EE application.
Online it describes how you should define the roles in sun-web.xml. However I would like to have all my roles, and groups defined in a database table.
That means, when I access a method for my application, the request needs to be intercepted to see if the user is allowed in the role.
Do I need to
create some kind of interceptor class that checks auth as user makes call to my web service method
create a custom Login Module that fishes out the group and role data from the database when a user first logs on
Any pointers would be really helpful.
First of all: I would strongly suggest using standard authorization mechanisms.
But for your use-case these standard mechanisms won't work, see this post: dynamic roles on a Java EE server
Roles have to be declared in the web.xml or sun-web.xml.
Frameworks
The next thing I would look into are frameworks, that could help you with that. The link will provide you with two suggested frameworks.
Building your own
If you don't need it for productive purposes, I would suggest the following:
use Filters to check for authorization and authentication: Filters a fairly easy to use ,very powerful and often used for security purposes: See http://docs.oracle.com/javaee/6/tutorial/doc/bnagb.html for more information about filter.
For the login, you could probably just stick with the standard form-based login.
I have a customer who wants to implement SSO using SAML2 assertion based approach. The customer will be the Identity Provider (IDP) and my application will effectively be the Service Provider (SP).
In the past I've implemented SSO solutions where the IDP was Oracle Access Manager and therefore we were provided with the idp.xml file which allowed us to configure our SP environment using the supplied Fedlet. This conveniently created a relevant WAR file which, when deployed, allowed me to distribute the sp.xml file to the customer who imported it into their IDP. This all worked fine and I understand the concepts i.e. We receive the initial request, the fedlet handles this and takes the user to the IDP where they authenticate, then they're passed back to our SP with a SAML response which the Fedlet allows us to parse and extract some data identifying the user. I then do what's required to sign them into our application.
However the current requirement is not using any backend framework to provide the IDP, they've stated that it's custom built one. They've given me the IDP URL and a cert file and are asking for our "AssertionConsumerServiceURL" and "AudienceURI".
The application which I'm enabling SSO for is largely Java based. My investigation so far has led me to Forgerock's OpenAM solution as well as Shibboleth's OpenSAML. However I'm struggling with the first step, essentially where do what I start building a custom SP application connecting to a third party IDP using OpenAM/Shibboleth/AnotherFramework.
Any pointers would be very useful.
Thanks,
Lee
Depends on what what you requirements are. OpenAM feldlet or Shibboleth i probably the best approach since you don't have to do so much coding on your own.
OpenSAML is a very low level toolkit for handling SAML messages. I would not recommend it if, not really needed.
As for the things they are asking for, the AssertionConsumerServiceURL is the service endpoint where you recieve your SSO SAML messages.
Defenition of AudienceURI is quite gray. Basically you send them an identifier, they include this in their messages and you validate that identifier is the same you gave them. I my self do not understand the difference between this and Destination...
I'm a bit surprised that they ask you for this. The standard way to do this first exchange of information is by SAML metadata documents.
As you may know OpenAM also provides the FedLet, which is a lightweight SAML2.0 SP implementation. If you want to do it all yourself you have to build an SAML2.0 SP yourself.
If you want to mess around with Spring you could also use Spring Security SAML2 extension ..'http://static.springsource.org/spring-security/site/extensions/saml/index.html'
Why roll out those heavy SAML solutions? Have you taken a look at PingOne APS (Application Provider Services) or PingFederate from Ping Identity? You can implement APS in less than a day and you first customer config is free. Includes dashboard reporting, IDP self service functionality for config and a dead simple REST API integration for your application. [Note: I work for Ping.]
You can setup the Spring Security SAML Extension. The extension creates an AssertionConsumerServiceURL and if they want to access your metadata just as you are accessing theirs, they would just need to go to www.yourwebsite.com/saml/metadata and your SP metadata will be downloaded by them.
We are planning on developing a layer of REST services to expose services hosted on a legacy system. These services will be used by a classic web application and native mobile phone applications.
This legacy system is secured in such a way that an initial username + password authentication is required (a process that can take 5 to 10 seconds). After the initial authentication, a time-constrained token is returned. This token must then be included in all further requests or else requests will be rejected.
Due to a security requirement, the legacy security token cannot be returned outside of the REST service layer. This means that the REST service layer needs to keep this token in some form of user session, or else the expensive username + password authentication process would need to be repeated for every call to the legacy system.
The REST service layer will be implemented using a Java 6 + Spring 3 + Spring Security 3 stack. At first sight, it looks like this setup will run fine: Spring-based REST services will be secured using a rather standard Spring Security configuration, the legacy security token will be stored in the user's HTTP session and every call will retrieve this token using the user's session and send it to the legacy system.
But there lies the question: how will REST clients send the necessary data so that the user's HTTP session is retrieved properly? This is normally done transparently by the web browser using the JSESSIONID cookie, but no browser is involved in this process. Sure, REST clients could add cookie management to their code, but is this an easy task for all Spring RestTemplate, iPhone, BlackBerry and Android clients?
The alternative would be to bypass the HTTP session at the REST service layer and use some other form of user session, maybe using a database, that would be identified using some key that would be sent by REST clients through a HTTP header or simple request query. The question then becomes, how can Spring Security be configured to use this alternative session mechanism instead of the standard Servlet HttpSession?
Surely I am not the first dealing with this situation. What am I missing?
Thanks!
There's nothing magical about cookies. They're just strings in HTTP headers. Any decent client API can handle them, although many require explicit configuration to enable cookie processing.
An alternative to using cookies is to put the JSESSIONID into the URL. I don't know anything about spring-security, but it seems that that's actually the default for at least some types of URL requests, unless disable-url-rewriting is explicitly set to true . This can be considered a security weakness, though.
Unfortunately authentication is highly problematic -- a bit of a blind spot in terms of web standards and browser implementations. You are right that cookies are not considered "RESTful" but purists, but even on fully-featured browsers avoiding takes quite a bit of hackery, as described in this article: Rest based authentication.
Unfortunately I haven't done any mobile development, so I can't suggest what the best compromise is. You might want to start by checking what authentication models each of your targetted platforms does support. In particular, two main options are:
HTTP authentication (ideally "digest", not "basic")
Cookies
One possibility would be to provide both options. Obviously not ideal from a technical or security point of view, but could have merits in terms of usability.