AuthorizationManagerBase.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */
  20. package org.openspcoop2.generic_project.utils;

  21. import java.util.Enumeration;
  22. import java.util.Properties;

  23. import javax.servlet.http.HttpServletRequest;

  24. import org.slf4j.Logger;
  25. import org.openspcoop2.generic_project.exception.NotAuthorizedException;
  26. import org.openspcoop2.generic_project.exception.ServiceException;
  27. import org.openspcoop2.utils.transport.http.HttpServletCredential;

  28. /**
  29.  * AuthorizationManager
  30.  *
  31.  * @author Poli Andrea (apoli@link.it)
  32.  * @author $Author$
  33.  * @version $Rev$, $Date$
  34.  */
  35. public class AuthorizationManagerBase {
  36.    
  37.     private boolean basic = false;
  38.     private boolean ssl = false;
  39.     private boolean principal = false;
  40.    
  41.     private boolean authorizedRequired;

  42.     private boolean identifiedMethodOrRelation = true;
  43.    
  44.     private Properties basicAuthorizedIdentitiesSearch = null;
  45.     private Properties basicAuthorizedIdentitiesCRUD = null;
  46.    
  47.     private Properties sslAuthorizedIdentitiesSearch = null;
  48.     private Properties sslAuthorizedIdentitiesCRUD = null;
  49.    
  50.     private Properties principalAuthorizedIdentitiesSearch = null;
  51.     private Properties principalAuthorizedIdentitiesCRUD = null;
  52.    
  53.     public AuthorizationManagerBase(Properties serverProperties) throws ServiceException{
  54.         this(new ServerPropertiesBase(serverProperties));
  55.     }
  56.     public AuthorizationManagerBase(ServerPropertiesBase serverProperties) throws ServiceException{
  57.        
  58.         String identifiedMethodOrRelationTmp = serverProperties.getProperty("identifiedMethod.orRelation", false);
  59.         if(identifiedMethodOrRelationTmp!=null){
  60.             this.identifiedMethodOrRelation = Boolean.parseBoolean(identifiedMethodOrRelationTmp);
  61.         }
  62.        
  63.         String authorizationMethodEnabled = serverProperties.getProperty("identifiedMethod", false);
  64.         if(authorizationMethodEnabled!=null){
  65.             String [] split = authorizationMethodEnabled.split(",");
  66.             for (int i = 0; i < split.length; i++) {
  67.                 String method = split[i].trim();
  68.                 if("basic".equalsIgnoreCase(method)){
  69.                     this.basic = true;
  70.                    
  71.                     Properties authBasicAll = serverProperties.readProperties("authorized.basic.");
  72.                     this.basicAuthorizedIdentitiesSearch = new Properties();
  73.                     this.basicAuthorizedIdentitiesSearch.putAll(authBasicAll);
  74.                     this.basicAuthorizedIdentitiesCRUD = new Properties();
  75.                     this.basicAuthorizedIdentitiesCRUD.putAll(authBasicAll);
  76.                    
  77.                     Properties authBasicSearch = serverProperties.readProperties("authorized.search.basic.");
  78.                     if(authBasicSearch.size()>0){
  79.                         Enumeration<?> en = authBasicSearch.keys();
  80.                         while (en.hasMoreElements()) {
  81.                             String key = (String) en.nextElement();
  82.                             if(this.basicAuthorizedIdentitiesSearch.containsKey(key)){
  83.                                 throw new ServiceException("Property ["+key+"] already defined for basic authentication of search method (see authorized.basic.* and authorized.search.basic.*)");
  84.                             }
  85.                             this.basicAuthorizedIdentitiesSearch.put(key, authBasicSearch.get(key));
  86.                         }
  87.                     }
  88.                    
  89.                     Properties authBasicCRUD = serverProperties.readProperties("authorized.crud.basic.");
  90.                     if(authBasicCRUD.size()>0){
  91.                         Enumeration<?> en = authBasicCRUD.keys();
  92.                         while (en.hasMoreElements()) {
  93.                             String key = (String) en.nextElement();
  94.                             if(this.basicAuthorizedIdentitiesCRUD.containsKey(key)){
  95.                                 throw new ServiceException("Property ["+key+"] already defined for basic authentication of crud method (see authorized.basic.* and authorized.crud.basic.*)");
  96.                             }
  97.                             this.basicAuthorizedIdentitiesCRUD.put(key, authBasicCRUD.get(key));
  98.                         }
  99.                     }
  100.                    
  101.                     if(this.basicAuthorizedIdentitiesCRUD.size()<=0 && this.basicAuthorizedIdentitiesSearch.size()<=0){
  102.                         throw new ServiceException("Required authorizedMethod ["+method+"] without a list of authorized users");
  103.                     }
  104.                 }
  105.                 else if("ssl".equalsIgnoreCase(method)){
  106.                     this.ssl = true;
  107.                    
  108.                     Properties authSslAll = serverProperties.readProperties("authorized.ssl.");
  109.                     this.sslAuthorizedIdentitiesSearch = new Properties();
  110.                     this.sslAuthorizedIdentitiesSearch.putAll(authSslAll);
  111.                     this.sslAuthorizedIdentitiesCRUD = new Properties();
  112.                     this.sslAuthorizedIdentitiesCRUD.putAll(authSslAll);
  113.                    
  114.                     Properties authSslSearch = serverProperties.readProperties("authorized.search.ssl.");
  115.                     if(authSslSearch.size()>0){
  116.                         Enumeration<?> en = authSslSearch.keys();
  117.                         while (en.hasMoreElements()) {
  118.                             String key = (String) en.nextElement();
  119.                             if(this.sslAuthorizedIdentitiesSearch.containsKey(key)){
  120.                                 throw new ServiceException("Property ["+key+"] already defined for ssl authentication of search method (see authorized.ssl.* and authorized.search.ssl.*)");
  121.                             }
  122.                             this.sslAuthorizedIdentitiesSearch.put(key, authSslSearch.get(key));
  123.                         }
  124.                     }
  125.                    
  126.                     Properties authSslCRUD = serverProperties.readProperties("authorized.crud.ssl.");
  127.                     if(authSslCRUD.size()>0){
  128.                         Enumeration<?> en = authSslCRUD.keys();
  129.                         while (en.hasMoreElements()) {
  130.                             String key = (String) en.nextElement();
  131.                             if(this.sslAuthorizedIdentitiesCRUD.containsKey(key)){
  132.                                 throw new ServiceException("Property ["+key+"] already defined for ssl authentication of crud method (see authorized.ssl.* and authorized.crud.ssl.*)");
  133.                             }
  134.                             this.sslAuthorizedIdentitiesCRUD.put(key, authSslCRUD.get(key));
  135.                         }
  136.                     }
  137.                    
  138.                     if(this.sslAuthorizedIdentitiesCRUD.size()<=0 && this.sslAuthorizedIdentitiesSearch.size()<=0){
  139.                         throw new ServiceException("Required authorizedMethod ["+method+"] without a list of authorized users");
  140.                     }
  141.                 }
  142.                 else if("principal".equalsIgnoreCase(method)){
  143.                     this.principal = true;
  144.                    
  145.                     Properties authPrincipalAll = serverProperties.readProperties("authorized.principal.");
  146.                     this.principalAuthorizedIdentitiesSearch = new Properties();
  147.                     this.principalAuthorizedIdentitiesSearch.putAll(authPrincipalAll);
  148.                     this.principalAuthorizedIdentitiesCRUD = new Properties();
  149.                     this.principalAuthorizedIdentitiesCRUD.putAll(authPrincipalAll);
  150.                    
  151.                     Properties authPrincipalSearch = serverProperties.readProperties("authorized.search.principal.");
  152.                     if(authPrincipalSearch.size()>0){
  153.                         Enumeration<?> en = authPrincipalSearch.keys();
  154.                         while (en.hasMoreElements()) {
  155.                             String key = (String) en.nextElement();
  156.                             if(this.principalAuthorizedIdentitiesSearch.containsKey(key)){
  157.                                 throw new ServiceException("Property ["+key+"] already defined for principal authentication of search method (see authorized.principal.* and authorized.search.principal.*)");
  158.                             }
  159.                             this.principalAuthorizedIdentitiesSearch.put(key, authPrincipalSearch.get(key));
  160.                         }
  161.                     }
  162.                    
  163.                     Properties authPrincipalCRUD = serverProperties.readProperties("authorized.crud.principal.");
  164.                     if(authPrincipalCRUD.size()>0){
  165.                         Enumeration<?> en = authPrincipalCRUD.keys();
  166.                         while (en.hasMoreElements()) {
  167.                             String key = (String) en.nextElement();
  168.                             if(this.principalAuthorizedIdentitiesCRUD.containsKey(key)){
  169.                                 throw new ServiceException("Property ["+key+"] already defined for principal authentication of crud method (see authorized.principal.* and authorized.crud.principal.*)");
  170.                             }
  171.                             this.principalAuthorizedIdentitiesCRUD.put(key, authPrincipalCRUD.get(key));
  172.                         }
  173.                     }
  174.                    
  175.                     if(this.principalAuthorizedIdentitiesCRUD.size()<=0 && this.principalAuthorizedIdentitiesSearch.size()<=0){
  176.                         throw new ServiceException("Required authorizedMethod ["+method+"] without a list of authorized users");
  177.                     }
  178.                 }
  179.                 else{
  180.                     throw new ServiceException("AuthorizedMethod ["+method+"] unknow");
  181.                 }
  182.             }
  183.         }
  184.        
  185.         this.authorizedRequired = this.basic || this.ssl || this.principal;
  186.     }

  187.     private void logError(Logger log,String message,StringBuilder bf){
  188.         if(bf.length()>0){
  189.             bf.append("\n");
  190.         }
  191.         bf.append(message);
  192.         log.error(message);
  193.     }
  194.    
  195.     public void authorize(HttpServletRequest httpServletRequest,Logger log,boolean searchMethod) throws NotAuthorizedException{
  196.        
  197.         if(this.authorizedRequired==false){
  198.             return;
  199.         }
  200.        
  201.         HttpServletCredential identity = new HttpServletCredential(httpServletRequest,log,true);
  202.         StringBuilder bf = new StringBuilder();
  203.        
  204.         boolean basicOk = false;
  205.         if(this.basic){
  206.             String username = identity.getUsername();
  207.             String password = identity.getPassword();
  208.             if(username!=null){
  209.                 if(password!=null){
  210.                     boolean isRegistered = false;
  211.                     String passwordRegistrata = null;
  212.                     if(searchMethod){
  213.                         isRegistered = this.basicAuthorizedIdentitiesSearch.containsKey(username);
  214.                         if(isRegistered){
  215.                             passwordRegistrata = this.basicAuthorizedIdentitiesSearch.getProperty(username);
  216.                         }
  217.                     }
  218.                     else{
  219.                         isRegistered = this.basicAuthorizedIdentitiesCRUD.containsKey(username);
  220.                         if(isRegistered){
  221.                             passwordRegistrata = this.basicAuthorizedIdentitiesCRUD.getProperty(username);
  222.                         }
  223.                     }
  224.                     if(isRegistered){
  225.                         if(password.equals(passwordRegistrata)){
  226.                             log.debug("Detected in the http request a credential basic (username:"+username+") that identifies an authorized user");
  227.                             basicOk = true;
  228.                         }else{
  229.                             logError(log, "Detected in the http request a credential basic (username:"+username
  230.                                     +") that contains a wrong password ["+password+"]", bf);
  231.                         }
  232.                     }else{
  233.                         logError(log, "Detected in the http request a credential basic (username:"+username+" password"+password
  234.                                 +") not authorized", bf);
  235.                     }
  236.                 }else{
  237.                     logError(log, "Detected in the http request a credential basic not usable (username:"+username
  238.                             +"), password not defined???", bf);
  239.                 }
  240.             }
  241.         }
  242.        
  243.         boolean sslOk = false;
  244.         if(this.ssl){
  245.             String subject = identity.getSubject();
  246.             if(subject!=null){
  247.                 boolean isRegistered = false;
  248.                 if(searchMethod){
  249.                     isRegistered = this.sslAuthorizedIdentitiesSearch.containsValue(subject);
  250.                 }
  251.                 else{
  252.                     isRegistered = this.sslAuthorizedIdentitiesCRUD.containsValue(subject);
  253.                 }
  254.                 if(isRegistered){
  255.                     log.debug("Detected in the http request a credential ssl (subject:"+subject+") that identifies an authorized user");
  256.                     sslOk = true;
  257.                 }else{
  258.                     logError(log, "Detected in the http request a credential ssl (subject:"+subject+") not authorized", bf);
  259.                 }
  260.             }
  261.         }
  262.        
  263.         boolean principalOk = false;
  264.         if(this.principal){
  265.             String principalId = identity.getPrincipal();
  266.             if(principalId!=null){
  267.                 boolean isRegistered = false;
  268.                 if(searchMethod){
  269.                     isRegistered = this.principalAuthorizedIdentitiesSearch.containsValue(principalId);
  270.                 }
  271.                 else{
  272.                     isRegistered = this.principalAuthorizedIdentitiesCRUD.containsValue(principalId);
  273.                 }
  274.                 if(isRegistered){
  275.                     log.debug("Detected in the http request a credential principal (id:"+principalId+") that identifies an authorized user");
  276.                     principalOk = true;
  277.                 }else{
  278.                     logError(log, "Detected in the http request a credential principal (id:"+principalId+") not authorized", bf);
  279.                 }
  280.             }
  281.         }
  282.        
  283.         if(this.identifiedMethodOrRelation){
  284.             if( !basicOk && !sslOk && !principalOk){
  285.                 if(bf.length()>0){
  286.                     throw new NotAuthorizedException(bf.toString());
  287.                 }
  288.                 else{
  289.                     throw new NotAuthorizedException("No credentials found in the request");
  290.                 }
  291.             }
  292.         }
  293.         else{
  294.             if(this.basic && !basicOk){
  295.                 if(bf.length()>0){
  296.                     throw new NotAuthorizedException(bf.toString());
  297.                 }
  298.                 else{
  299.                     throw new NotAuthorizedException("No basic credentials found in the request");
  300.                 }
  301.             }
  302.             if(this.ssl && !sslOk){
  303.                 if(bf.length()>0){
  304.                     throw new NotAuthorizedException(bf.toString());
  305.                 }
  306.                 else{
  307.                     throw new NotAuthorizedException("No ssl credentials found in the request");
  308.                 }
  309.             }
  310.             if(this.principal && !principalOk){
  311.                 if(bf.length()>0){
  312.                     throw new NotAuthorizedException(bf.toString());
  313.                 }
  314.                 else{
  315.                     throw new NotAuthorizedException("No principal credentials found in the request");
  316.                 }
  317.             }
  318.         }
  319.        
  320.     }
  321.    
  322. }