Package org.hornetq.integration.jboss.security

Source Code of org.hornetq.integration.jboss.security.JBossASSecurityManager

/*
* Copyright 2005-2014 Red Hat, Inc.
* Red Hat licenses this file to you 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.hornetq.integration.jboss.security;

import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.util.HashSet;
import java.util.Set;

import javax.naming.InitialContext;
import javax.security.auth.Subject;

import org.hornetq.core.security.CheckType;
import org.hornetq.core.security.Role;
import org.hornetq.core.server.HornetQComponent;
import org.hornetq.integration.jboss.HornetQJBossLogger;
import org.hornetq.spi.core.security.HornetQSecurityManager;
import org.jboss.security.AuthenticationManager;
import org.jboss.security.RealmMapping;
import org.jboss.security.SecurityContext;
import org.jboss.security.SecurityContextAssociation;
import org.jboss.security.SimplePrincipal;

/**
* This implementation delegates to the JBoss AS security interfaces (which in turn use JAAS)
* It can be used when running HornetQ in JBoss AS
*
* @author <a href="ataylor@redhat.com">Andy Taylor</a>
* @author <a href="tim.fox@jboss.com">Tim Fox</a>
*/
public class JBossASSecurityManager implements HornetQSecurityManager, HornetQComponent
{
   // Static --------------------------------------------------------

   // Attributes ----------------------------------------------------

   private final boolean trace = HornetQJBossLogger.LOGGER.isTraceEnabled();

   /**
    * the realmmapping
    */
   private RealmMapping realmMapping;

   /**
    * the JAAS Authentication Manager
    */
   private AuthenticationManager authenticationManager;

   /**
    * The JNDI name of the AuthenticationManager(and RealmMapping since they are the same object).
    */
   private String securityDomainName = "java:/jaas/hornetq";

   private boolean started;

   private boolean isAs5 = true;

   private boolean allowClientLogin = false;

   private boolean authoriseOnClientLogin = false;

   public boolean validateUser(final String user, final String password)
   {
      SimplePrincipal principal = new SimplePrincipal(user);

      char[] passwordChars = null;

      if (password != null)
      {
         passwordChars = password.toCharArray();
      }

      Subject subject = new Subject();

      return authenticationManager.isValid(principal, passwordChars, subject);
   }

   public boolean validateUserAndRole(final String user,
                                      final String password,
                                      final Set<Role> roles,
                                      final CheckType checkType)
   {
      if (allowClientLogin && SecurityContextAssociation.isClient())
      {
         return authoriseOnClientLogin ? useClientAuthentication(roles, checkType) : true;
      }
      else
      {
         return useConnectionAuthentication(user, password, roles, checkType);
      }
   }

   private boolean useConnectionAuthentication(final String user,
                                               final String password,
                                               final Set<Role> roles,
                                               final CheckType checkType)
   {
      return AccessController.doPrivileged(new PrivilegedAction<Boolean>()
      {
         public Boolean run()
         {

            SimplePrincipal principal = user == null ? null : new SimplePrincipal(user);

            char[] passwordChars = null;

            if (password != null)
            {
               passwordChars = password.toCharArray();
            }

            Subject subject = new Subject();

            boolean authenticated = authenticationManager.isValid(principal, passwordChars, subject);
            // Authenticate. Successful authentication will place a new SubjectContext on thread local,
            // which will be used in the authorization process. However, we need to make sure we clean up
            // thread local immediately after we used the information, otherwise some other people
            // security my be screwed up, on account of thread local security stack being corrupted.
            if (authenticated)
            {
               pushSecurityContext(principal, passwordChars, subject);
               Set<Principal> rolePrincipals = getRolePrincipals(checkType, roles);

               authenticated = realmMapping.doesUserHaveRole(principal, rolePrincipals);

               if (trace)
               {
                  HornetQJBossLogger.LOGGER.trace("user " + user +
                                                   (authenticated ? " is " : " is NOT ") +
                                                   "authorized");
               }
               popSecurityContext();
            }
            return authenticated;
         }
      });
   }

   private boolean useClientAuthentication(final Set<Role> roles, final CheckType checkType)
   {
      return AccessController.doPrivileged(new PrivilegedAction<Boolean>()
      {
         public Boolean run()
         {
            SecurityContext sc = SecurityContextAssociation.getSecurityContext();
            Principal principal = sc.getUtil().getUserPrincipal();

            char[] passwordChars = (char[])sc.getUtil().getCredential();

            Subject subject = sc.getSubjectInfo().getAuthenticatedSubject();

            boolean authenticated = authenticationManager.isValid(principal, passwordChars, subject);

            if (authenticated)
            {
               Set<Principal> rolePrincipals = getRolePrincipals(checkType, roles);

               authenticated = realmMapping.doesUserHaveRole(principal, rolePrincipals);

               if (trace)
               {
                  HornetQJBossLogger.LOGGER.trace("user " + principal.getName() +
                                                   (authenticated ? " is " : " is NOT ") +
                                                   "authorized");
               }
            }
            return authenticated;
         }

      });

   }

   private void popSecurityContext()
   {
      if (isAs5)
      {
         SecurityActions.popSubjectContext();
      }
      else
      {
         AS4SecurityActions.popSubjectContext();
      }
   }

   private void pushSecurityContext(final SimplePrincipal principal, final char[] passwordChars, final Subject subject)
   {
      if (isAs5)
      {
         SecurityActions.pushSubjectContext(principal, passwordChars, subject, securityDomainName);
      }
      else
      {
         AS4SecurityActions.pushSubjectContext(principal, passwordChars, subject);
      }
   }

   public void addRole(final String user, final String role)
   {
      // NO-OP
   }

   public void addUser(final String user, final String password)
   {
      // NO-OP
   }

   public void removeRole(final String user, final String role)
   {
      // NO-OP
   }

   public void removeUser(final String user)
   {
      // NO-OP
   }

   public void setDefaultUser(final String username)
   {
      // NO-OP
   }

   private Set<Principal> getRolePrincipals(final CheckType checkType, final Set<Role> roles)
   {
      Set<Principal> principals = new HashSet<Principal>();
      for (Role role : roles)
      {
         if (checkType.hasRole(role))
         {
            principals.add(new SimplePrincipal(role.getName()));
         }
      }
      return principals;
   }

   public void setRealmMapping(final RealmMapping realmMapping)
   {
      this.realmMapping = realmMapping;
   }

   public void setAuthenticationManager(final AuthenticationManager authenticationManager)
   {
      this.authenticationManager = authenticationManager;
   }

   /**
    * lifecycle method, needs to be called
    *
    * @throws Exception
    */
   public synchronized void start() throws Exception
   {
      if (started)
      {
         return;
      }

      InitialContext ic = new InitialContext();
      authenticationManager = (AuthenticationManager)ic.lookup(securityDomainName);
      realmMapping = (RealmMapping)authenticationManager;

      started = true;
   }

   public synchronized void stop()
   {
      if (!started)
      {
         return;
      }
      started = false;
   }

   public synchronized boolean isStarted()
   {
      return started;
   }

   public void setSecurityDomainName(final String securityDomainName)
   {
      this.securityDomainName = securityDomainName;
   }

   public void setAs5(final boolean as5)
   {
      isAs5 = as5;
   }

   public void setAllowClientLogin(final boolean allowClientLogin)
   {
      this.allowClientLogin = allowClientLogin;
   }

   public void setAuthoriseOnClientLogin(final boolean authoriseOnClientLogin)
   {
      this.authoriseOnClientLogin = authoriseOnClientLogin;
   }
}
TOP

Related Classes of org.hornetq.integration.jboss.security.JBossASSecurityManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.