alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Jetty example source code file (FormAuthenticator.java)

This example Jetty source code file (FormAuthenticator.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Jetty tags/keywords

auth, failure, form, form, formcredential, formcredential, http, io, ioexception, logout, principal, request, request, response, security, servlet, ssorealm, ssorealm, string, string

The Jetty FormAuthenticator.java source code

// ========================================================================
// Copyright 199-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// 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.
// ========================================================================

package org.mortbay.jetty.security;

import java.io.IOException;
import java.io.Serializable;
import java.security.Principal;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

import org.mortbay.jetty.Request;
import org.mortbay.jetty.Response;
import org.mortbay.log.Log;
import org.mortbay.util.StringUtil;
import org.mortbay.util.URIUtil;


/* ------------------------------------------------------------ */
/** FORM Authentication Authenticator.
 * The HTTP Session is used to store the authentication status of the
 * user, which can be distributed.
 * If the realm implements SSORealm, SSO is supported.
 *
 * @author Greg Wilkins (gregw)
 * @author dan@greening.name
 */
public class FormAuthenticator implements Authenticator
{
    /* ------------------------------------------------------------ */
    public final static String __J_URI="org.mortbay.jetty.URI";
    public final static String __J_AUTHENTICATED="org.mortbay.jetty.Auth";
    public final static String __J_SECURITY_CHECK="/j_security_check";
    public final static String __J_USERNAME="j_username";
    public final static String __J_PASSWORD="j_password";

    private String _formErrorPage;
    private String _formErrorPath;
    private String _formLoginPage;
    private String _formLoginPath;
    
    /* ------------------------------------------------------------ */
    public String getAuthMethod()
    {
        return HttpServletRequest.FORM_AUTH;
    }

    /* ------------------------------------------------------------ */
    public void setLoginPage(String path)
    {
        if (!path.startsWith("/"))
        {
            Log.warn("form-login-page must start with /");
            path="/"+path;
        }
        _formLoginPage=path;
        _formLoginPath=path;
        if (_formLoginPath.indexOf('?')>0)
            _formLoginPath=_formLoginPath.substring(0,_formLoginPath.indexOf('?'));
    }

    /* ------------------------------------------------------------ */
    public String getLoginPage()
    {
        return _formLoginPage;
    }
    
    /* ------------------------------------------------------------ */
    public void setErrorPage(String path)
    {
        if (path==null || path.trim().length()==0)
        {
            _formErrorPath=null;
            _formErrorPage=null;
        }
        else
        {
            if (!path.startsWith("/"))
            {
                Log.warn("form-error-page must start with /");
                path="/"+path;
            }
            _formErrorPage=path;
            _formErrorPath=path;

            if (_formErrorPath!=null && _formErrorPath.indexOf('?')>0)
                _formErrorPath=_formErrorPath.substring(0,_formErrorPath.indexOf('?'));
        }
    }    

    /* ------------------------------------------------------------ */
    public String getErrorPage()
    {
        return _formErrorPage;
    }
    
    /* ------------------------------------------------------------ */
    /** Perform form authentication.
     * Called from SecurityHandler.
     * @return UserPrincipal if authenticated else null.
     */
    public Principal authenticate(UserRealm realm,
                                  String pathInContext,
                                  Request request,
                                  Response response)
        throws IOException
    {
        // Handle paths
        String uri = pathInContext;

        // Setup session 
        HttpSession session=request.getSession(response!=null);
        if (session==null)
            return null;
        
        // Handle a request for authentication.
        // TODO perhaps j_securitycheck can be uri suffix?
        if ( uri.endsWith(__J_SECURITY_CHECK) )
        {
            // Check the session object for login info.
            FormCredential form_cred=new FormCredential();
            form_cred.authenticate(realm,
                                            request.getParameter(__J_USERNAME),
                                            request.getParameter(__J_PASSWORD),
                                            request);
            
            String nuri=(String)session.getAttribute(__J_URI);
            if (nuri==null || nuri.length()==0)
            {
                nuri=request.getContextPath();
                if (nuri.length()==0)
                    nuri=URIUtil.SLASH;
            }
            
            if (form_cred._userPrincipal!=null)
            {
                // Authenticated OK
                if(Log.isDebugEnabled())Log.debug("Form authentication OK for "+form_cred._jUserName);
                session.removeAttribute(__J_URI); // Remove popped return URI.
                request.setAuthType(Constraint.__FORM_AUTH);
                request.setUserPrincipal(form_cred._userPrincipal);
                session.setAttribute(__J_AUTHENTICATED,form_cred);

                // Sign-on to SSO mechanism
                if (realm instanceof SSORealm)
                    ((SSORealm)realm).setSingleSignOn(request,response,form_cred._userPrincipal,new Password(form_cred._jPassword));

                // Redirect to original request
                if (response != null) {
                    response.setContentLength(0);
                    response.sendRedirect(response.encodeRedirectURL(nuri));
                }
            }   
            else
            {
                if(Log.isDebugEnabled())Log.debug("Form authentication FAILED for "+StringUtil.printable(form_cred._jUserName));
                if (_formErrorPage==null)
                {
                    if (response != null) 
                        response.sendError(HttpServletResponse.SC_FORBIDDEN);
                }
                else
                {
                    if (response != null)
                        response.setContentLength(0);
                        response.sendRedirect(response.encodeRedirectURL
                                          (URIUtil.addPaths(request.getContextPath(),
                                                        _formErrorPage)));
                }
            }
            
            // Security check is always false, only true after final redirection.
            return null;
        }
        
        // Check if the session is already authenticated.
        FormCredential form_cred = (FormCredential) session.getAttribute(__J_AUTHENTICATED);
        
        if (form_cred != null)
        {
            // We have a form credential. Has it been distributed?
            if (form_cred._userPrincipal==null)
            {
                // This form_cred appears to have been distributed.  Need to reauth
                form_cred.authenticate(realm, request);
                
                // Sign-on to SSO mechanism
                if (form_cred._userPrincipal!=null && realm instanceof SSORealm)
                    ((SSORealm)realm).setSingleSignOn(request,response,form_cred._userPrincipal,new Password(form_cred._jPassword));
                
            }
            else if (!realm.reauthenticate(form_cred._userPrincipal))
                // Else check that it is still authenticated.
                form_cred._userPrincipal=null;

            // If this credential is still authenticated
            if (form_cred._userPrincipal!=null)
            {
                if(Log.isDebugEnabled())Log.debug("FORM Authenticated for "+form_cred._userPrincipal.getName());
                request.setAuthType(Constraint.__FORM_AUTH);
                request.setUserPrincipal(form_cred._userPrincipal);
                return form_cred._userPrincipal;
            }
            else
                session.setAttribute(__J_AUTHENTICATED,null);
        }
        else if (realm instanceof SSORealm)
        {
            // Try a single sign on.
            Credential cred = ((SSORealm)realm).getSingleSignOn(request,response);
            
            if (request.getUserPrincipal()!=null)
            {
                form_cred=new FormCredential();
                form_cred._userPrincipal=request.getUserPrincipal();
                form_cred._jUserName=form_cred._userPrincipal.getName();
                if (cred!=null)
                    form_cred._jPassword=cred.toString();
                if(Log.isDebugEnabled())Log.debug("SSO for "+form_cred._userPrincipal);
                           
                request.setAuthType(Constraint.__FORM_AUTH);
                session.setAttribute(__J_AUTHENTICATED,form_cred);
                return form_cred._userPrincipal;
            }
        }
        
        // Don't authenticate authform or errorpage
        if (isLoginOrErrorPage(pathInContext))
            return SecurityHandler.__NOBODY;
        
        // redirect to login page
        if (response!=null)
        {
            if (request.getQueryString()!=null)
                uri+="?"+request.getQueryString();
            session.setAttribute(__J_URI, 
                                 request.getScheme() +
                                 "://" + request.getServerName() +
                                 ":" + request.getServerPort() +
                                 URIUtil.addPaths(request.getContextPath(),uri));
            response.setContentLength(0);
            response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getContextPath(),
                                                                          _formLoginPage)));
        }

        return null;
    }

    public boolean isLoginOrErrorPage(String pathInContext)
    {
        return pathInContext!=null &&
         (pathInContext.equals(_formErrorPath) || pathInContext.equals(_formLoginPath));
    }
    
    /* ------------------------------------------------------------ */
    /** FORM Authentication credential holder.
     */
    private static class FormCredential implements Serializable, HttpSessionBindingListener
    {
        String _jUserName;
        String _jPassword;
        transient Principal _userPrincipal;
        transient UserRealm _realm;

        void authenticate(UserRealm realm,String user,String password,Request request)
        {
            _jUserName=user;
            _jPassword=password;
            _userPrincipal = realm.authenticate(user, password, request);
            if (_userPrincipal!=null)
                _realm=realm;
            else
            {
                Log.warn("AUTH FAILURE: user {}",StringUtil.printable(user));
                request.setUserPrincipal(null);
            }
        }

        void authenticate(UserRealm realm,Request request)
        {
            _userPrincipal = realm.authenticate(_jUserName, _jPassword, request);
            if (_userPrincipal!=null)
                _realm=realm;
            else
            {
                Log.warn("AUTH FAILURE: user {}",StringUtil.printable(_jUserName));
                request.setUserPrincipal(null);
            }
        }
        

        public void valueBound(HttpSessionBindingEvent event) {}
        
        public void valueUnbound(HttpSessionBindingEvent event)
        {
            if(Log.isDebugEnabled())Log.debug("Logout "+_jUserName);
            
            if(_realm instanceof SSORealm)
                ((SSORealm)_realm).clearSingleSignOn(_jUserName);
               
            if(_realm!=null && _userPrincipal!=null)
                _realm.logout(_userPrincipal); 
        }
        
        public int hashCode()
        {
            return _jUserName.hashCode()+_jPassword.hashCode();
        }

        public boolean equals(Object o)
        {
            if (!(o instanceof FormCredential))
                return false;
            FormCredential fc = (FormCredential)o;
            return
                _jUserName.equals(fc._jUserName) &&
                _jPassword.equals(fc._jPassword);
        }

        public String toString()
        {
            return "Cred["+_jUserName+"]";
        }

    }
}

Other Jetty examples (source code examples)

Here is a short list of links related to this Jetty FormAuthenticator.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.