Impedir que usuarios privilegiados se registren externamente

El archivo wc-server.xml incluye una cabecera de servidor web personalizable. Puede editar esta cabecera para controlar si los usuarios privilegiados pueden iniciar la sesión en la tienda desde redes externas. Esta infraestructura reduce la posibilidad de un ataque externo si una cuenta con el acceso a nivel administrativo, como un representante del serivico al cliente o administrador del sitio se ve comprometida.

La siguiente configuración de seguridad wc-server.xml define la cabecera de solicitud personalizada EXTERNAL_WEBSERVER:
<RestrictAdminLogonToStore display="false" enabled="false" webServerHeader="EXTERNAL_WEBSERVER">
    <RolesAllowedWithoutHeader>
        <Role name="Registered Customer"/>
        <Role name="Buyer Administrator"/>
        <Role name="Buyer Approver"/>
    </RolesAllowedWithoutHeader>
</RestrictAdminLogonToStore>

De forma predeterminada la función está inhabilitada, pero puede habilitarla (enabled="true"). Después de que la infraestructura esté habilitada, puede definir una cabecera personalizada (EXTERNAL_WEBSERVER) y listar los roles de usuario específicos permitidos para acceder al sitio desde redes externas. Los roles están definidos en la cabecera <RolesAllowedWithoutHeader>. Con estas propiedades definidas, puede especificar la cabecera identificada en servidores web que están sirviendo a tráfico externo; los servidores web que están sirviendo a tráfico interno eliminarán esta cabecera. De este modo, si la cabecera personalizada está presente en una solicitud web (tráfico externo), solo los usuarios con roles definidos en <RolesAllowedWithoutHeader> (o usuarios no autenticados) tienen autorización para acceder al sitio (se bloquearía un representante del servicio al cliente, un administrador de sitio u otro rol de parte vendedora). Si la cabecera está ausente de la solicitud (tráfico interno), un usuario con cualquier rol puede acceder al sitio.

Si utiliza IBM HTTP Server, puede añadir lo siguiente a httpd.conf para añadir el valor de cabecera EXTERNAL_WEBSERVER de <code>true</code> al objeto HttpServletRequest:
RequestHeader set EXTERNAL_WEBSERVER true
En el ejemplo, sólo los usuarios con los roles siguientes (o sin ningún rol) pueden acceder al sitio externamente cuando la cabecera está presente en la solicitud web:
  • Cliente registrado
  • Administrador de compradores
  • Aprobador de compradores

Punto de extensión para personalización

Esta infraestructura contiene un mandato de tarea CheckLogonAllowedCmd que se puede utilizar como un punto de extensión para la personalización. El comportamiento predeterminado utiliza CheckLogonAllowedCmdImpl, que implementa el método público isAllowed(). Este método devuelve true si se recibe la solicitud de inicio de sesión desde la red interna; de lo contrario comprueba los roles de usuario en los roles definidos en la sección <RolesAllowedWithoutHeader> del archivo wc-server.xml .

Con la cabecera personalizada EXTERNAL_WEBSERVER establecida en REST o la cabecera de solicitud web, getExternalWebServerFlag() del método CheckLogonAllowedCmdImpl detecta el valor y devuelve true para indicar que la solicitud es de una red externa.

En un caso de ejemplo en el que isAllowed() devuelve false, se emite el siguiente código de error nuevo:
  • ERR_LOGON_NOT_ALLOWED_FROM_EXTERNAL_WEBSITE = "2340";
La captura de pantalla siguiente ilustra el código de error en el escaparate:

Utilizando esta infraestructura, puede adoptar dos planteamientos posibles para controlar el acceso de red interno y externo al sitio. Recuerde que no está limitados a estos planteamientos.
  1. Controle el acceso interno y externo a través de servidores web separados. Establezca la cabecera personalizada especificada en cada solicitud desde el servidor web para impedir que los usuarios privilegiados inicien la sesión en el sitio externamente.
  2. Utilice un filtro personalizado, que se describe a continuación, para validar la información de solicitud para diferenciar solicitudes de red internas de externas.

Código de ejemplo para personalización

El código de ejemplo siguiente se puede utilizar para personalización a fin de habilitar la comprobación de inicio de sesión externa en la tienda. Este ejemplo utiliza la creación de un nuevo filtro, que determina si se recibe la solicitud entrante desde un sitio web externo. En este caso, la dirección IP es para esta determinación. El filtro siguiente se puede añadir al archivo web.xml de la tienda:
public class MyRuntimeServletFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
        throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest)req;
        // limit filter to only logon request
        if (httpServletRequest.getPathInfo()!= null && httpServletRequest.getPathInfo().contains("AjaxLogon")) {
            String customHeaderName = WcsApp.configProperties.getValue(ECSecurityConstants.WCSAPP_CUSTOM_HEADER_URL);
            // check RestrictAdminLogonToServer is enabled and custom header is set in wc-server.xml
            if (SecurityHelper.isRestrictAdminLogonToStore() && customHeaderName != null) {
                String remoteIP = null;
                if (httpServletRequest.getHeader("x-forwarded-for") == null) {  
                    remoteIP = httpServletRequest.getRemoteAddr();  
                } else {
                    remoteIP = httpServletRequest.getHeader("x-forwarded-for");  
                } 
                if (remoteIP != null && remoteIP.startsWith("9.186")) {
                   // set external network request flag
                    SecurityHelper.setExternalWebServerFlag(customHeaderName, Boolean.TRUE);
                }
            }
        }
        chain.doFilter(req, res); 
    }
Nota: SecurityHelper.setExternalWebServerFlag() es un programa de utilidad en la clase SecurityHelper que ayuda a establecer el indicador personalizado en la memoria caché de transacción. Asegúrese de añadir el filtro personalizado como filtro final en el archivo web.xml porque el almacenamiento caché de transacción no se puede borrar mediante una operación de transacción en otros filtros.