Package org.jboss.identity.federation.web.handlers.saml2

Source Code of org.jboss.identity.federation.web.handlers.saml2.SAML2LogOutHandler$SPLogOutHandler

/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file 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.identity.federation.web.handlers.saml2;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.jboss.identity.federation.api.saml.v2.request.SAML2Request;
import org.jboss.identity.federation.api.saml.v2.response.SAML2Response;
import org.jboss.identity.federation.core.exceptions.ConfigurationException;
import org.jboss.identity.federation.core.exceptions.ProcessingException;
import org.jboss.identity.federation.core.saml.v2.common.IDGenerator;
import org.jboss.identity.federation.core.saml.v2.constants.JBossSAMLURIConstants;
import org.jboss.identity.federation.core.saml.v2.interfaces.SAML2Handler;
import org.jboss.identity.federation.core.saml.v2.interfaces.SAML2HandlerRequest;
import org.jboss.identity.federation.core.saml.v2.interfaces.SAML2HandlerResponse;
import org.jboss.identity.federation.core.saml.v2.interfaces.SAML2HandlerRequest.GENERATE_REQUEST_TYPE;
import org.jboss.identity.federation.core.saml.v2.util.XMLTimeUtil;
import org.jboss.identity.federation.saml.v2.SAML2Object;
import org.jboss.identity.federation.saml.v2.protocol.LogoutRequestType;
import org.jboss.identity.federation.saml.v2.protocol.ObjectFactory;
import org.jboss.identity.federation.saml.v2.protocol.RequestAbstractType;
import org.jboss.identity.federation.saml.v2.protocol.ResponseType;
import org.jboss.identity.federation.saml.v2.protocol.StatusCodeType;
import org.jboss.identity.federation.saml.v2.protocol.StatusResponseType;
import org.jboss.identity.federation.saml.v2.protocol.StatusType;
import org.jboss.identity.federation.web.core.HTTPContext;
import org.jboss.identity.federation.web.core.IdentityServer;
import org.xml.sax.SAXException;

/**
* SAML2 LogOut Profile
* @author Anil.Saldhana@redhat.com
* @since Sep 17, 2009
*/
public class SAML2LogOutHandler extends BaseSAML2Handler
   private static Logger log = Logger.getLogger(SAML2LogOutHandler.class);
   private boolean trace = log.isTraceEnabled();
  
   private IDPLogOutHandler idp = new IDPLogOutHandler();
   private SPLogOutHandler sp = new SPLogOutHandler();
  
   private ObjectFactory objectFactory = new ObjectFactory();
  
   /**
    * @see SAML2Handler#generateSAMLRequest(SAML2HandlerRequest, SAML2HandlerResponse)
    */
   public void generateSAMLRequest(SAML2HandlerRequest request, SAML2HandlerResponse response)
         throws ProcessingException
   {
      if(request.getTypeOfRequestToBeGenerated() == null)
      {
         if(trace)
         {
            log.trace("Request type to be generated=null");
         }
         return;
      }
      if(GENERATE_REQUEST_TYPE.LOGOUT != request.getTypeOfRequestToBeGenerated())
         return;
     
     
      if(request.getType() == SAML2HandlerRequest.HANDLER_TYPE.IDP)
      {
         idp.generateSAMLRequest(request, response);
      }
      else
      {
         sp.generateSAMLRequest(request, response);
      }
   }
  
   /**
    * @see SAML2Handler#handleRequestType(RequestAbstractType)
    */
   public void handleRequestType(SAML2HandlerRequest request,
         SAML2HandlerResponse response) throws ProcessingException
   {
      if(request.getSAML2Object() instanceof LogoutRequestType == false)
         return ;
     
      if(request.getType() == SAML2HandlerRequest.HANDLER_TYPE.IDP)
      {
         idp.handleRequestType(request, response);
      }
      else
      {
         sp.handleRequestType(request, response);
      }
   }

   /**
    * @see SAML2Handler#handleStatusResponseType(StatusResponseType,
         Document resultingDocument)
    */
   public void handleStatusResponseType(SAML2HandlerRequest request,
         SAML2HandlerResponse response) throws ProcessingException
   {
      //we do not handle any ResponseType (authentication etc)
      if(request.getSAML2Object() instanceof ResponseType)
         return;
        
      if(request.getSAML2Object() instanceof StatusResponseType == false)
         return ;
     
      if(request.getType() == SAML2HandlerRequest.HANDLER_TYPE.IDP)
      {
         idp.handleStatusResponseType(request, response);
      }
      else
      {
         sp.handleStatusResponseType(request, response);
      }
   }
  
   private class IDPLogOutHandler
   {
      public void generateSAMLRequest(SAML2HandlerRequest request,
            SAML2HandlerResponse response) throws ProcessingException
      {
        
      }
     
     
      public void handleStatusResponseType( SAML2HandlerRequest request,
             SAML2HandlerResponse response ) throws ProcessingException
     
         //we got a logout response from a SP
         SAML2Object samlObject = request.getSAML2Object();
         StatusResponseType statusResponseType = (StatusResponseType) samlObject;
        
         HTTPContext httpContext = (HTTPContext) request.getContext();
         HttpServletRequest httpRequest = httpContext.getRequest();
         HttpSession httpSession = httpRequest.getSession(false);
        
         String relayState = request.getRelayState();
        
         ServletContext servletCtx = httpContext.getServletContext();
         IdentityServer server = (IdentityServer)servletCtx.getAttribute("IDENTITY_SERVER");
        
         if(server == null)
            throw new ProcessingException("Identity Server not found");
        
         String sessionID = httpSession.getId();
        
         String statusIssuer = statusResponseType.getIssuer().getValue();
         server.stack().deRegisterTransitParticipant(sessionID, statusIssuer);
        
         String nextParticipant = this.getParticipant(server, sessionID, relayState);
         if(nextParticipant == null || nextParticipant.equals(relayState))
         {
            //we are done with logout
           
            //TODO: check the in transit map for partial logouts

            try
            {
               generateSuccessStatusResponseType(statusResponseType.getInResponseTo(),
                     request, response, relayState);
            }
            catch (Exception e)
            {
               throw new ProcessingException(e);
            }
         }
         else
         {
            //Put the participant in transit mode
            server.stack().registerTransitParticipant(sessionID, nextParticipant);
                     
            //send logout request to participant with relaystate to orig
            response.setRelayState(relayState);
           
            response.setDestination(nextParticipant);
           
            SAML2Request saml2Request = new SAML2Request();
            try
            {
               LogoutRequestType lort = saml2Request.createLogoutRequest(request.getIssuer().getValue());
               response.setResultingDocument(saml2Request.convert(lort));
            }
            catch(Exception e)
            {
               throw new ProcessingException(e);
            }
         }
      }
     
      public void handleRequestType( SAML2HandlerRequest request,
            SAML2HandlerResponse response ) throws ProcessingException
      {
         HTTPContext httpContext = (HTTPContext) request.getContext();
         HttpSession session = httpContext.getRequest().getSession(false);
         String sessionID = session.getId();
        
         String relayState = httpContext.getRequest().getParameter("RelayState");
        
         LogoutRequestType logOutRequest = (LogoutRequestType) request.getSAML2Object();
         String issuer = logOutRequest.getIssuer().getValue();
         try
         {
            SAML2Response saml2Response = new SAML2Response();
            SAML2Request saml2Request = new SAML2Request();
           
            ServletContext servletCtx = httpContext.getServletContext();
            IdentityServer server = (IdentityServer)servletCtx.getAttribute("IDENTITY_SERVER");
           
            if(server == null)
               throw new ProcessingException("Identity Server not found");
           
            String originalIssuer = (relayState == null) ? issuer : relayState;
           
            String participant = this.getParticipant(server, sessionID, originalIssuer);
          
            if(participant == null || participant.equals(originalIssuer))
            {
               //All log out is done
               session.invalidate();
               server.stack().pop(sessionID);
              
               generateSuccessStatusResponseType(logOutRequest.getID(),
                     request, response, originalIssuer);
            }
            else
            {
               //Put the participant in transit mode
               server.stack().registerTransitParticipant(sessionID, participant);
              
               if(relayState == null)
                  relayState = originalIssuer;
              
               //send logout request to participant with relaystate to orig
               response.setRelayState(originalIssuer);
              
               response.setDestination(participant);
              
              
               LogoutRequestType lort = saml2Request.createLogoutRequest(request.getIssuer().getValue());
               response.setResultingDocument(saml2Request.convert(lort));
            }
         }
         catch(ParserConfigurationException pe)
         {
            throw new ProcessingException(pe);
         }
         catch(ConfigurationException pe)
         {
            throw new ProcessingException(pe);
         }
         catch(JAXBException pe)
         {
            throw new ProcessingException(pe);
         }
         catch(IOException pe)
         {
            throw new ProcessingException(pe);
         }
         catch(SAXException pe)
         {
            throw new ProcessingException(pe);
         }
         return;
      }


      private void generateSuccessStatusResponseType(
            String logOutRequestID,
            SAML2HandlerRequest request,
            SAML2HandlerResponse response,
            String originalIssuer)
            throws ConfigurationException, ParserConfigurationException, ProcessingException
      {
         StatusResponseType statusResponse = objectFactory.createStatusResponseType();
        
         //Status
         StatusType statusType = objectFactory.createStatusType();
         StatusCodeType statusCodeType = objectFactory.createStatusCodeType();
         statusCodeType.setValue(JBossSAMLURIConstants.STATUS_RESPONDER.get());
        
         //2nd level status code
         StatusCodeType status2ndLevel = objectFactory.createStatusCodeType();
         status2ndLevel.setValue(JBossSAMLURIConstants.STATUS_SUCCESS.get());
         statusCodeType.setStatusCode(status2ndLevel);
        
         statusType.setStatusCode(statusCodeType);
        
         statusResponse.setStatus(statusType);
        
         statusResponse.setIssueInstant(XMLTimeUtil.getIssueInstant());
         statusResponse.setInResponseTo(logOutRequestID);
         statusResponse.setID(IDGenerator.create("ID_"));
        
         statusResponse.setIssuer(request.getIssuer());
        
         try
         {
            SAML2Response saml2Response = new SAML2Response();
            response.setResultingDocument(saml2Response.convert(statusResponse));
         }
         catch(JAXBException je)
         {
            throw new ProcessingException(je);
         }
        
         response.setDestination(originalIssuer);
      }
     
      private String getParticipant(IdentityServer server, String sessionID,
            String originalRequestor)
      {
         int participants = server.stack().getParticipants(sessionID);
        
         String participant = originalRequestor;
         //Get a participant who is not equal to the original issuer of the logout request
         if(participants > 0)
         {
            do
            {
               participant = server.stack().pop(sessionID);
               --participants;  
            }
            while(participants > 0 && participant.equals(originalRequestor));
         }
        
        return participant;
      }
   }
  
   private class SPLogOutHandler
   {
      public void generateSAMLRequest(SAML2HandlerRequest request,
            SAML2HandlerResponse response) throws ProcessingException
      {
         //Generate the LogOut Request
         SAML2Request samlRequest = new SAML2Request();
         try
         {
            LogoutRequestType lot =
               samlRequest.createLogoutRequest(request.getIssuer().getValue());
            response.setResultingDocument(samlRequest.convert(lot));
         }
         catch (Exception e)
         {
            throw new ProcessingException(e);
         }
      }
     
      public void handleStatusResponseType( SAML2HandlerRequest request,
            SAML2HandlerResponse response ) throws ProcessingException
      {
         //Handler a log out response from IDP
         StatusResponseType statusResponseType = (StatusResponseType) request.getSAML2Object();
        
         HTTPContext httpContext = (HTTPContext) request.getContext();
         HttpServletRequest servletRequest = httpContext.getRequest();
         HttpSession session = servletRequest.getSession(false);
        
         //TODO: Deal with partial logout report
        
         StatusType statusType = statusResponseType.getStatus();
         StatusCodeType statusCode = statusType.getStatusCode();
         StatusCodeType secondLevelstatusCode = statusCode.getStatusCode();
         if(secondLevelstatusCode.getValue().equals(JBossSAMLURIConstants.STATUS_SUCCESS.get()))
         {
            //we are successfully logged out
            session.invalidate();
         }
      }
     
      public void handleRequestType( SAML2HandlerRequest request, 
            SAML2HandlerResponse response ) throws ProcessingException
     
         SAML2Object samlObject = request.getSAML2Object();
         if(samlObject instanceof LogoutRequestType == false)
            return;
        
         LogoutRequestType logOutRequest = (LogoutRequestType) samlObject;
         HTTPContext httpContext = (HTTPContext) request.getContext();
         HttpServletRequest servletRequest = httpContext.getRequest();
         HttpSession session = servletRequest.getSession(false);
        
         String relayState = servletRequest.getParameter("RelayState");
        
         session.invalidate(); //Invalidate the current session at the SP
        
         //Generate a Logout Response
         StatusResponseType statusResponse = objectFactory.createStatusResponseType();
        
         //Status
         StatusType statusType = objectFactory.createStatusType();
         StatusCodeType statusCodeType = objectFactory.createStatusCodeType();
         statusCodeType.setValue(JBossSAMLURIConstants.STATUS_RESPONDER.get());
        
         //2nd level status code
         StatusCodeType status2ndLevel = objectFactory.createStatusCodeType();
         status2ndLevel.setValue(JBossSAMLURIConstants.STATUS_SUCCESS.get());
         statusCodeType.setStatusCode(status2ndLevel);
        
         statusType.setStatusCode(statusCodeType);
        
         statusResponse.setStatus(statusType);
        
         try
         {
            statusResponse.setIssueInstant(XMLTimeUtil.getIssueInstant());
         }
         catch (ConfigurationException e)
         {
            throw new ProcessingException(e);
         }
         statusResponse.setInResponseTo(logOutRequest.getID());
         statusResponse.setID(IDGenerator.create("ID_"));
        
         statusResponse.setIssuer(request.getIssuer());
        
         SAML2Response saml2Response = new SAML2Response();
         try
         {
            response.setResultingDocument(saml2Response.convert(statusResponse));
         }
         catch(Exception je)
         {
            throw new ProcessingException(je);
         }
        
         response.setRelayState(relayState);
         response.setDestination(logOutRequest.getIssuer().getValue());
      }
   }

   public void reset() throws ProcessingException
   {
      // TODO Auto-generated method stub
     
   }
}
TOP

Related Classes of org.jboss.identity.federation.web.handlers.saml2.SAML2LogOutHandler$SPLogOutHandler

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.