PicketLink

PicketLink is security management system developed by JBoss.
If you use PicketLink, you don’t have to create your own authentication system by filter and so on.
There are many examples at here.
I will introduce picketlink-http-servlet-integration in this examples.
This example shows integration of PicketLink and servlet.

Copyright of this example is as follows.

JBoss, Home of Professional Open Source
Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
contributors by the @authors tag. See the copyright.txt in the 
distribution for a full listing of individual contributors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,  
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Environment
PicketLink 2.7.0.Final
WildFly 8.2.0.Final

Condition
CDI
Servlet 3.0
EJB 3.1

picketlink-http-servlet-integration.war
A war file is as follows.
picketlink-http-servlet-int

/WEB-INF/beans.xml

<!-- Marker file indicating CDI should be enabled -->
<beans xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
      http://java.sun.com/xml/ns/javaee 
      http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

This file is required in order to activate CDI.

SecurityInitializer.java

package org.picketlink.quickstarts.http.servlet;

import org.picketlink.idm.IdentityManager;
import org.picketlink.idm.PartitionManager;
import org.picketlink.idm.RelationshipManager;
import org.picketlink.idm.credential.Password;
import org.picketlink.idm.model.basic.Role;
import org.picketlink.idm.model.basic.User;

import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.inject.Inject;

import static org.picketlink.idm.model.basic.BasicModel.grantRole;

/**
 * This startup bean creates a number of default users, groups and roles when the application is started.
 * 
 * @author Pedro Igor
 */
@Singleton
@Startup
public class SecurityInitializer {

    @Inject
    private PartitionManager partitionManager;

    @PostConstruct
    public void create() {
        // Create user john
        User john = new User("john");

        IdentityManager identityManager = this.partitionManager.createIdentityManager();

        identityManager.add(john);
        identityManager.updateCredential(john, new Password("john"));

        Role userRole = new Role("User");

        identityManager.add(userRole);

        // Create application role "adminRole"
        Role adminRole = new Role("Administrator");

        identityManager.add(adminRole);

        RelationshipManager relationshipManager = this.partitionManager.createRelationshipManager();

        // Grant the "userRole" application role to john
        grantRole(relationshipManager, john, userRole);
    }
}

At line 22, @Singleton indicates this class is singleton session bean.
As @Startup exists at line 23, this class will execute when this application starts and create method is executed.
User object at line 32 is prepared by PicketLink. This object treats user information.
User john is created at here.
After that, user john is registerd and password is set as john.
After line 39, role is created. Here, User role and Administrator role are created.
At line 51, User john is granted User role.

HttpSecurityConfiguration.java

package org.picketlink.quickstarts.http.servlet;

import org.picketlink.event.SecurityConfigurationEvent;

import javax.enterprise.event.Observes;

/**
 * @author Pedro Igor
 */
public class HttpSecurityConfiguration {

    /**
     * <p>Tells PicketLink to listen for all paths of the application. Please, notice that no security policy was defined
     * such as authentication or authorization. We're just enabling the PicketLink Security Filter.</p>
     *
     * @param event
     */
    public void onInit(@Observes SecurityConfigurationEvent event) {
        event.getBuilder()
            .http()
                .allPaths();
    }

}

At line 18, argument of onInit method has @Observes SecurityConfigurationEvent. When securityConfigurationEvent was fired, this method is called by CDI.
At line 21, allPaths method tells PicketLink to listen for all paths of the application. Please, notice that no security policy was defined such as authentication or authorization. This method is just enabling the PicketLink Security Filter.

AuthenticationServlet.java

package org.picketlink.quickstarts.http.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Pedro Igor
 */
@WebServlet ("/servlet")
public class AuthenticationServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        if (isLogout(req)) {
            req.logout();
        }

        tryAuthentication(req);

        resp.sendRedirect(req.getContextPath() + "/index.jsp");
    }

    private boolean isLogout(HttpServletRequest req) {
        return req.getUserPrincipal() != null && req.getParameter("logout") != null;
    }

    private void tryAuthentication(HttpServletRequest req) throws ServletException {
        if (req.getUserPrincipal() == null) {
            String username = req.getParameter("username");
            String password = req.getParameter("password");

            if (username != null && password != null) {
                req.login(username, password);
            }
        }
    }
}

As there is @WebServlet (“/servlet”) at line 13, service method of this servlet is called when /servlet was requested.
At line 18, logout is executed when authenticated user sent logout parameter. A logout method at line 19 is servlet method.
A tryAuthentication method at line 22 authenticate user. A login method at line 37 is servlet method.
At line 24, redirect to /index.jsp is executed regardless authentication result.

/index.jsp

<!-- Plain HTML page that kicks us into the app -->

<html>
<body>
    <%
        if (request.getUserPrincipal() == null) {
    %>
        <form method="post" action="<%= request.getContextPath() %>/servlet">
            Username: <input type="text" name="username"/><br/>
            Password: <input type="password" name="password"/>
            <br/>
            <br/>
            <input type="submit" value="Ok"/>
        </form>
    <%
        } else {
    %>
        Welcome, <%= request.getUserPrincipal().getName() %> !!
        <br/>
        <br/>
        Are you granted with the User Role ? request.isUserInRole("User") == <%= request.isUserInRole("User") %>.
        <br/>
        Are you an Administrator ? request.isUserInRole("Administrator") == <%= request.isUserInRole("Administrator") %>.
        <br/>
        <br/>
        Click here to <a href="<%= request.getContextPath() %>/servlet?logout=true">logout</a>.
    <%
        }
    %>
</body>
</html>

As authentication is not done at first access, request.getUserPrincipal() at line 6 is null and displayed authentication form.
picketlink-http-servlet-for
When user inputed username and password and clicked [Ok] button, AuthenticationServlet.java is executed and redirected to this file regardless authentication result.
Username and password were set SecurityInitializer.java(john/john).
When authentication failed, authentication form is displayed because request.getUserPrincipal() is null.
When authentication was success, message is displayed.
picketlink-http-servlet-log
As user john was granted User role at SecurityInitializer.java, request.isUserInRole(“User”) at line 21 returns true and request.isUserInRole(“Administrator”) at line 23 returns false.
When user clicked logout link, AuthenticationServlet.java will be executed and redirected to this file after logout.
After logout, authentication form is displayed because request.getUserPrincipal() is null.

Edit
2015-07-09 Modified description of /WEB-INF/beans.xml.