All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.security.auth.message.config.JBossServerAuthContext Maven / Gradle / Ivy

/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.security.auth.message.config;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.message.AuthException;
import javax.security.auth.message.AuthStatus;
import javax.security.auth.message.MessageInfo;
import javax.security.auth.message.ServerAuth;
import javax.security.auth.message.config.ServerAuthContext;
import javax.security.auth.message.module.ServerAuthModule;

import org.jboss.logging.Logger;
import org.jboss.security.config.ControlFlag;

//$Id: JBossServerAuthContext.java 2 2010-02-09 17:42:37Z  $

/**
 *  Default Server Authentication Context
 *  @author Anil Saldhana
 *  @since  May 17, 2006 
 *  @version $Revision: 2 $
 */
public class JBossServerAuthContext implements ServerAuthContext
{  
   protected static Logger log = Logger.getLogger(JBossServerAuthContext.class);
   
   protected boolean trace = log.isTraceEnabled();
   
   private List modules = new ArrayList(); 
   
   @SuppressWarnings("unchecked")
   private Map moduleOptionsByName = new HashMap();
   
   /**
    * Control Flags for the individual modules
    */
   protected List controlFlags = new ArrayList();
   
   @SuppressWarnings("unchecked")
   public JBossServerAuthContext(List modules,
         Map moduleNameToOptions, CallbackHandler cbh) throws AuthException
   {
      this.modules = modules;
      this.moduleOptionsByName = moduleNameToOptions;
      for(ServerAuthModule sam:modules)
      {
         sam.initialize(null, null, cbh, 
               moduleOptionsByName.get(sam.getClass().getName())); 
      }
   }
   
   public void setControlFlags(List controlFlags)
   {
      this.controlFlags = controlFlags;
   }
   
   
   /**
    * @see ServerAuth#cleanSubject(Subject, Map)
    */
   public void cleanSubject(MessageInfo messageInfo, Subject subject) throws AuthException
   { 
      for(ServerAuthModule sam:modules)
      {
         sam.cleanSubject(messageInfo, subject);
      }
   }
   
   /**
    * @see ServerAuth#secureResponse(AuthParam, Subject, Map)
    */
   public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject) throws AuthException
   { 
      AuthStatus status = null; 
      for(ServerAuthModule sam:modules)
      {
         status = sam.secureResponse(messageInfo, serviceSubject);
      }
      return status;
   }
   
   /**
    * @see ServerAuth#validateRequest(AuthParam, Subject, Subject, Map)
    */
   @SuppressWarnings("unchecked")
   public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, 
         Subject serviceSubject) throws AuthException
   { 
      List supportingModules = new ArrayList();
      
      Class requestType = messageInfo.getRequestMessage().getClass();
      Class[] requestInterfaces = requestType.getInterfaces(); 
      
      List intfaee = Arrays.asList(requestInterfaces);
      
      for(ServerAuthModule sam:modules)
      { 
         List supportedTypes = Arrays.asList(sam.getSupportedMessageTypes());
         
         //Check the interfaces
         for(Class clazz:intfaee)
         {
            if(supportedTypes.contains(clazz) && !supportingModules.contains(sam)) 
               supportingModules.add(sam);
         } 
         
         //Check the class type also
         if((supportedTypes.contains(Object.class) || supportedTypes.contains(requestType))
               && !supportingModules.contains(sam)) 
            supportingModules.add(sam); 
      }
      if(supportingModules.size() == 0)
         throw new RuntimeException("No ServerAuthModule configured to support type:"+requestType);
      
      AuthStatus authStatus = invokeModules(messageInfo, clientSubject, serviceSubject);
      return authStatus;
      
      /*for(ServerAuthModule sam:supportingModules)
      {
         status = sam.validateRequest(messageInfo, clientSubject, serviceSubject);
         if(status == AuthStatus.FAILURE)
            break;
      }
      return status;*/
   } 
   
   private AuthStatus invokeModules(MessageInfo messageInfo,
         Subject clientSubject, Subject serviceSubject) 
   throws AuthException
   {
      //Control Flag behavior
      boolean encounteredRequiredError = false; 
      boolean encounteredOptionalError = false; 
      AuthException moduleException = null;
      AuthStatus overallDecision = AuthStatus.FAILURE;
      
      int length = modules.size();
      for(int i = 0; i < length; i++)
      {
         ServerAuthModule module = (ServerAuthModule)modules.get(i);
         ControlFlag flag = (ControlFlag)this.controlFlags.get(i); 
         AuthStatus decision = AuthStatus.FAILURE;
         try
         {
            decision = module.validateRequest(messageInfo, clientSubject, serviceSubject);
         }
         catch(Exception ae)
         { 
            decision = AuthStatus.FAILURE;
            if(moduleException == null)
               moduleException = new AuthException(ae.getMessage());
         }
         
         if(decision == AuthStatus.SUCCESS)
         { 
            overallDecision =  AuthStatus.SUCCESS;
            //SUFFICIENT case
            if(flag == ControlFlag.SUFFICIENT && encounteredRequiredError == false)
               return AuthStatus.SUCCESS;
            continue; //Continue with the other modules
         }
         //Go through the failure cases 
         //REQUISITE case
         if(flag == ControlFlag.REQUISITE)
         {
            if(trace)
               log.trace("REQUISITE failed for " + module); 
            if(moduleException == null)
               moduleException = new AuthException("Auth  failed");
            else
               throw moduleException;
         }
         //REQUIRED Case
         if(flag == ControlFlag.REQUIRED)
         {
            if(trace)
               log.trace("REQUIRED failed for " + module);
            if(encounteredRequiredError == false)
               encounteredRequiredError = true;
         }
         if(flag == ControlFlag.OPTIONAL)
            encounteredOptionalError = true; 
      }
      
      //All the authorization modules have been visited.
      String msg = getAdditionalErrorMessage(moduleException);
      if(encounteredRequiredError)
         throw new AuthException("Auth Failed:"+ msg);
      if(overallDecision == AuthStatus.FAILURE && encounteredOptionalError)
         throw new AuthException("Auth Failed:" + msg);
      if(overallDecision == AuthStatus.FAILURE)
         throw new AuthException("Auth Failed:Denied.");
      return AuthStatus.SUCCESS;
   }
   

   private String getAdditionalErrorMessage(Exception e)
   {
      StringBuilder msg = new StringBuilder(" ");
      if(e != null)
         msg.append(e.getLocalizedMessage());
      return msg.toString();
   }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy