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

Glassfish example source code file (JAASRealm.java)

This example Glassfish source code file (JAASRealm.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 - Glassfish tags/keywords

arraylist, arraylist, genericprincipal, group, jaas, jaasrealm, lifecycleexception, log, logging, principal, principal, security, string, string, subject, throwable, throwable, util

The Glassfish JAASRealm.java source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 *
 *
 * This file incorporates work covered by the following copyright and
 * permission notice:
 *
 * Copyright 2004 The Apache Software Foundation
 *
 * 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.apache.catalina.realm;


import org.apache.catalina.Container;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.util.StringManager;

import javax.security.auth.Subject;
import javax.security.auth.login.*;
import java.security.Principal;
import java.security.acl.Group;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * <p>Implementation of Realm that authenticates users via the Java
 * Authentication and Authorization Service</em> (JAAS).  JAAS support requires
 * either JDK 1.4 (which includes it as part of the standard platform) or
 * JDK 1.3 (with the plug-in <code>jaas.jar file).

* * <p>The value configured for the appName property is passed to * the <code>javax.security.auth.login.LoginContext constructor, to * specify the <em>application name
used to select the set of relevant * <code>LoginModules required.

* * <p>The JAAS Specification describes the result of a successful login as a * <code>javax.security.auth.Subject instance, which can contain zero * or more <code>java.security.Principal objects in the return value * of the <code>Subject.getPrincipals() method. However, it provides * no guidance on how to distinguish Principals that describe the individual * user (and are thus appropriate to return as the value of * request.getUserPrincipal() in a web application) from the Principal(s) * that describe the authorized roles for this user. To maintain as much * independence as possible from the underlying <code>LoginMethod * implementation executed by JAAS, the following policy is implemented by * this Realm:</p> * <ul> * <li>The JAAS LoginModule is assumed to return a * <code>Subject with at least one Principal instance * representing the user himself or herself, and zero or more separate * <code>Principals representing the security roles authorized * for this user.</li> * <li>On the Principal representing the user, the Principal * name is an appropriate value to return via the Servlet API method * <code>HttpServletRequest.getRemoteUser(). * <li>On the Principals representing the security roles, the * name is the name of the authorized security role.</li> * <li>This Realm will be configured with two lists of fully qualified Java * class names of classes that implement * <code>java.security.Principal - one that identifies class(es) * representing a user, and one that identifies class(es) representing * a security role.</li> * <li>As this Realm iterates over the Principals returned by * <code>Subject.getPrincipals(), it will identify the first * <code>Principal that matches the "user classes" list as the * <code>Principal for this user. * <li>As this Realm iterates over the Principals returned by * <code>Subject.getPrincipals(), it will accumulate the set of * all <code>Principals matching the "role classes" list as * identifying the security roles for this user.</li> * <li>It is a configuration error for the JAAS login method to return a * validated <code>Subject without a Principal that * matches the "user classes" list.</li> * </ul> * * @author Craig R. McClanahan * @version $Revision: 1.3 $ $Date: 2006/03/12 01:27:04 $ */ public class JAASRealm extends RealmBase { private static Logger log = Logger.getLogger(JAASRealm.class.getName()); // ----------------------------------------------------- Instance Variables /** * The application name passed to the JAAS <code>LoginContext, * which uses it to select the set of relevant <code>LoginModules. */ protected String appName = null; /** * Descriptive information about this Realm implementation. */ protected static final String info = "org.apache.catalina.realm.JAASRealm/1.0"; /** * Descriptive information about this Realm implementation. */ protected static final String name = "JAASRealm"; /** * The list of role class names, split out for easy processing. */ protected ArrayList roleClasses = new ArrayList(); /** * The string manager for this package. */ protected static final StringManager sm = StringManager.getManager(Constants.Package); /** * The set of user class names, split out for easy processing. */ protected ArrayList userClasses = new ArrayList(); // ------------------------------------------------------------- Properties /** * setter for the appName member variable * @deprecated JAAS should use the Engine ( domain ) name and webpp/host overrides */ public void setAppName(String name) { appName = name; } /** * getter for the appName member variable */ public String getAppName() { return appName; } public void setContainer(Container container) { super.setContainer(container); String name=container.getName(); if( appName==null ) { appName=name; log.info("Setting JAAS app name " + appName); } } /** * Comma-delimited list of <code>javax.security.Principal classes * that represent security roles. */ protected String roleClassNames = null; public String getRoleClassNames() { return (this.roleClassNames); } public void setRoleClassNames(String roleClassNames) { this.roleClassNames = roleClassNames; roleClasses.clear(); String temp = this.roleClassNames; if (temp == null) { return; } while (true) { int comma = temp.indexOf(','); if (comma < 0) { break; } roleClasses.add(temp.substring(0, comma).trim()); temp = temp.substring(comma + 1); } temp = temp.trim(); if (temp.length() > 0) { roleClasses.add(temp); } } /** * Comma-delimited list of <code>javax.security.Principal classes * that represent individual users. */ protected String userClassNames = null; public String getUserClassNames() { return (this.userClassNames); } public void setUserClassNames(String userClassNames) { this.userClassNames = userClassNames; userClasses.clear(); String temp = this.userClassNames; if (temp == null) { return; } while (true) { int comma = temp.indexOf(','); if (comma < 0) { break; } userClasses.add(temp.substring(0, comma).trim()); temp = temp.substring(comma + 1); } temp = temp.trim(); if (temp.length() > 0) { userClasses.add(temp); } } // --------------------------------------------------------- Public Methods /** * Return the Principal associated with the specified username and * credentials, if there is one; otherwise return <code>null. * * If there are any errors with the JDBC connection, executing * the query or anything we return null (don't authenticate). This * event is also logged, and the connection will be closed so that * a subsequent request will automatically re-open it. * * @param username Username of the Principal to look up * @param credentials Password or other credentials to use in * authenticating this username */ public Principal authenticate(String username, char[] credentials) { // Establish a LoginContext to use for authentication try { LoginContext loginContext = null; if( appName==null ) appName="Tomcat"; if (log.isLoggable(Level.FINE)) log.fine("Authenticating " + appName + " " + username); // What if the LoginModule is in the container class loader ? // ClassLoader ocl=Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); try { loginContext = new LoginContext (appName, new JAASCallbackHandler(this, username, credentials)); } catch (Throwable e) { log.fine("Error initializing JAAS: " + e.toString()); log.log(Level.FINE, sm.getString("jaasRealm.loginException", username), e); return (null); } finally { Thread.currentThread().setContextClassLoader(ocl); } if (log.isLoggable(Level.FINE)) log.fine("Login context created " + username); // Negotiate a login via this LoginContext Subject subject = null; try { loginContext.login(); subject = loginContext.getSubject(); if (subject == null) { if (log.isLoggable(Level.FINE)) log.fine(sm.getString("jaasRealm.failedLogin", username)); return (null); } } catch (AccountExpiredException e) { if (log.isLoggable(Level.FINE)) log.fine(sm.getString("jaasRealm.accountExpired", username)); return (null); } catch (CredentialExpiredException e) { if (log.isLoggable(Level.FINE)) log.fine(sm.getString("jaasRealm.credentialExpired", username)); return (null); } catch (FailedLoginException e) { if (log.isLoggable(Level.FINE)) log.fine(sm.getString("jaasRealm.failedLogin", username)); return (null); } catch (LoginException e) { log.log(Level.FINE, sm.getString("jaasRealm.loginException", username), e); return (null); } catch (Throwable e) { log.log(Level.FINE, "Unexpected error", e); return (null); } if( log.isLoggable(Level.FINE)) log.fine("Getting principal " + subject); // Return the appropriate Principal for this authenticated Subject Principal principal = createPrincipal(username, subject); if (principal == null) { log.fine(sm.getString("jaasRealm.authenticateFailure", username)); return (null); } if (log.isLoggable(Level.FINE)) { log.fine(sm.getString("jaasRealm.authenticateSuccess", username)); } return (principal); } catch( Throwable t) { log.log(Level.SEVERE, "error ", t); return null; } } // -------------------------------------------------------- Package Methods // ------------------------------------------------------ Protected Methods /** * Return a short name for this Realm implementation. */ protected String getName() { return (this.name); } /** * Return the password associated with the given principal's user name. */ protected char[] getPassword(String username) { return (null); } /** * Return the Principal associated with the given user name. */ protected Principal getPrincipal(String username) { return (null); } /** * Construct and return a <code>java.security.Principal instance * representing the authenticated user for the specified Subject. If no * such Principal can be constructed, return <code>null. * * @param subject The Subject representing the logged in user */ protected Principal createPrincipal(String username, Subject subject) { // Prepare to scan the Principals for this Subject char[] password = null; // Will not be carried forward ArrayList roles = new ArrayList(); // Scan the Principals for this Subject Iterator principals = subject.getPrincipals().iterator(); while (principals.hasNext()) { Principal principal = (Principal) principals.next(); // No need to look further - that's our own stuff if( principal instanceof GenericPrincipal ) { if (log.isLoggable(Level.FINE)) log.fine("Found old GenericPrincipal " + principal ); return principal; } String principalClass = principal.getClass().getName(); if (log.isLoggable(Level.FINE)) log.fine("Principal: " + principalClass + " " + principal); if (userClasses.contains(principalClass)) { // Override the default - which is the original user, accepted by // the friendly LoginManager username = principal.getName(); } if (roleClasses.contains(principalClass)) { roles.add(principal.getName()); } // Same as Jboss - that's a pretty clean solution if( (principal instanceof Group) && "Roles".equals( principal.getName())) { Group grp=(Group)principal; Enumeration en=grp.members(); while( en.hasMoreElements() ) { Principal roleP=(Principal)en.nextElement(); roles.add( roleP.getName()); } } } // Create the resulting Principal for our authenticated user if (username != null) { return (new GenericPrincipal(this, username, password, roles)); } else { return (null); } } // ------------------------------------------------------ Lifecycle Methods /** * * Prepare for active use of the public methods of this Component. * * @exception LifecycleException if this component detects a fatal error * that prevents it from being started */ public void start() throws LifecycleException { // Perform normal superclass initialization super.start(); } /** * Gracefully shut down active use of the public methods of this Component. * * @exception LifecycleException if this component detects a fatal error * that needs to be reported */ public void stop() throws LifecycleException { // Perform normal superclass finalization super.stop(); } }

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish JAASRealm.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.