- Google Accounts API
- Using Google Accounts API, you can allow users to login to your app using their google account (gmail id).
- Federated Login
- Using Federated Login, you can allow users to login using any OpenID identity provider (Yahoo, Google Apps account etc.)
The focus of this post is to explain the latter using Google Apps Domain as the identity provider. If you are interested in learning about the former, you can refer to this link. Google App Engine team did a good job of documenting this approach whereas documentation for federated login approach is not comprehensive.
Here are the requirements we are going to fulfill in this example:
- Provide users ability to login using their Google Apps email ID
- Provide users ability to invoke your app from their google apps universal navigation bar [SSO implementation - users should not be prompted to enter their password again because they are already logged into their google apps].
How-to
- Set authentication option in Google App Engine Settings to Federated Login
- Set up security constraints in web.xml so that when users go to any of your app urls directly, App Engine will prompt them for authentication. When App Engine encounters a url that needs to be accessed only by logged in users and the user is not logged in, it directs the user to URL /_ah/login_required. You will have to create a servlet that handle requests to this URL. We will address this an a later step but it's important to keep in mind that /_ah/login_required URL itself should be accessible without user being logged in. Otherwise, it would result in a recursion error.
<security-constraint>
<web-resource-collection>
<web-resource-name>accessible without login</web-resource-name>
<url-pattern>/_ah/login_required</url-pattern>
</web-resource-collection>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name> accessible with login</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
- Create servlet mapping for the servlet you'll be creating to handle requests to /_ah/login_required URL
<servlet>
<servlet-name>LoginRequiredServlet</servlet-name>
<servlet-class>com.yourcompany.server.LoginRequiredServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginRequiredServlet</servlet-name>
<url-pattern>/_ah/login_required</url-pattern>
</servlet-mapping>
- Create a simple login page to which LoginRequiredServlet can direct users to for entry of login id/domain
- In LoginRequiredServlet, use App Engine's UserService class to create login url and redirect user to that url if the user is not already logged in
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
if (user != null) {
//Forward the user to you app start page
} else {
//forwardingUrl is the link to which you want user to be
// sent to after successful authentication
String loginUrl = userService.createLoginURL(forwardingUrl,
null, domain, null);
resp.sendRedirect(loginUrl);
}
You will find more information the following article useful:
Using Federated Authentication via OpenID in Google App Engine