LPS:Java-idp-webauth-login-handler

Z HelpDesk


Webauth Login Handler

WebAuth is an authentication system for web pages and web applications. If we want use Webauth as login service for our IdP realm. We want to use it like RemoteUserLoginHandler. Webauth WAS module (mod_webauth) which handles authentication of user based on cookie token webauth_at sets environment variable REMOTE_USER/WEBAUTH_USER for backend application engine (eg. IdP). But it's SSO, and by default RemoteUser cann't do force authentication by itself.

        ForceAuthn [Optional]
2042    A Boolean value. If "true", the identity provider MUST authenticate the presenter directly rather than
2043    rely on a previous security context. If a value is not provided, the default is "false". However, if both
2044    ForceAuthn and IsPassive are "true", the identity provider MUST NOT freshly authenticate the
2045    presenter unless the constraints of IsPassive can be met.

Overview

Authentication tokens generated by mod_webauth and mod_webkdc are of certain properties. For normal requests, we find any valid webauth token as sufficient authentication for IdP. In case of ForceAuthn request to IdP, we need login handler to force user to get a token with a specific properties. We consider valid ForceAuthn token that is:

  • based on knowledge of login/password
  • not older than X minutes
  • not used in IdP before (eg. not presenting any previous security context ;)

All token constraints are validated in WebauthAuthServlet.java:service(..). We followed this path:

   /** Webauth Login function  
    * 
    * when force auth is requested we consider several use cases:
    *
    *  1) client was authenticated to IDP mod_webauth by SSO weblogin token (WEBAUTH_SESSION_FACTORS == c) 
    *   >> we need to force reauth on weblogin
    *    
    *  2) client was authenticated to IDP mod_webauth by weblogin by password (WEBAUTH_SESSION_FACTORS == p)
    *     but a long time ago, most likely that IDP is first requested resource  in WebAuth SSO domain
    *   >> we need to force reauth on weblogin if webauth_at is older than X minutes
    *    
    *  3) client was authenticated to IDP mod_webauth by weblogin by password (WEBAUTH_SESSION_FACTORS == p)
    *     short time ago, but still we "MUST NOT rely on previous security context"
    *     http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf
    *     so we'll check all services the user is logged in, and insist that WEBAUTH_TOKEN_CREATION is newer
    *     also, if idpSession not exists (but new token is presented) or list of used services is empty
    *   >> we need to force reauth on weblogin if webauth_at is not newer or sufficient ...
    * 
    *  4) client was reauthenticated to another application within same FQDN as IDP (cookie: webauth_at;domain=FQDN;path=/)
    *      - tokens has (WEBAUTH_SESSION_FACTORS == p); 
    *      - token is new (age < X minutes)
    *      - is newer than any other login to any service
    *   >> we can manage that IDP doesn't not share webauth login context (eg. webauth_at cookie scope) 
    *      with any other application
    *  
    *  5) client was reauthenticated to another application within WebSSO domain (not related to IDP was in any way)
    *  so, token is new, based od password and is newer than IDP saw a last time
    *      - tokens has (WEBAUTH_SESSION_FACTORS == p); 
    *      - token is new (age < X minutes)
    *      - is newer than any other login to any service
    *   >> this is not the case, since webauth_at is not shared among different FQDNs
    *      
    *  so we want:
    *  1)  - WEBAUTH_SESSION_FACTORS == p; any other factor is considered not sufficient
    *        we consider "p" and only "p" secure method of auth, we don't oxkm anyway, but that might not be fine for other sites (TODO)
    *
    *  2)  - WEBAUTH_TOKEN_CREATION must be new, not older than X minutes
    *        IDP can be first WAS authenticated in browser, so token can be P but very old ...
    * 
    *  3)  - WEBAUTH_TOKEN_CREATION > any login time to any service
    *        (saml specification -- not rely on previous sec context -- webauth_at)
    * 
    * 
    *  4)  - there is no other application on IDP FQDN 
    *        this is a deployment constraint
    * 
    */

Theese steps should lead to situation, that for old security context Shibboleth and Webauth asks user for a login/password. Which we consider as reauthentication. We did not consider other auth factors as sufficient, as some of them might be...

Requirements

  • IdP must be only application in webauth_at cookie scope (have it's own FQDN)
  • IdP webcontainer must be bind behind httpd through mod_jk
  • Webauth >= 4.x

Installation and configuration

  • get the source code and build IdP module
  • install and configure handler
  • configure handler/authentication servlet
  • configure webauth reauth helper (session factors requester)


Download and build

Download and build the source (replace X.0 with the last stable version, e.g.: "tags/1.0"):

git clone https://home.zcu.cz/~bodik/java-idp-webauth-login-handler
cd java-idp-webauth-login-handler
mvn package

Install and configure handler

Copy the .jar file to the installation folder:

cp target/webauth-login-handler-X.0.jar $IDP_INSTALL_DIR/lib

handler.xml configuration

Configure the handler.xml at:

  • new install: $IDP_INSTALL_DIR/src/installer/resources/conf-tmpl/handler.xml
  • reinstall: $IDP_DIR/conf/handler.xml

<ph:ProfileHandlerGroup xmlns:ph="urn:mace:shibboleth:2.0:idp:profile-handler" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  (...)
  xmlns:webauth="http://support.zcu.cz/java-idp-webauth-login-handler"                                      <<<<<
  (...)
  xsi:schemaLocation="
    urn:mace:shibboleth:2.0:idp:profile-handler classpath:/schema/shibboleth-2.0-idp-profile-handler.xsd
    http://support.zcu.cz/java-idp-webauth-login-handler classpath:/schema/webauth-login-handler.xsd        <<<<<
(...)
">
(...)
  <ph:LoginHandler xsi:type="webauth:Webauth">                                                              <<<<<
    <ph:AuthenticationMethod>urn:oasis:names:tc:SAML:2.0:ac:classes:Webauth</ph:AuthenticationMethod>       <<<<<
  </ph:LoginHandler>                                                                                        <<<<<
(...)
</ph:ProfileHandlerGroup>

Configure authentication servlet

In the web-application you have to enable the Webauth login servlet. You do that in $IDP_INSTALL_DIR/src/main/webapp/WEB-INF/web.xml:

<webapp>
(...)
  <servlet>
    <servlet-name>WebauthAuthServlet</servlet-name>
    <servlet-class>cz.zcu.civ.idp.webauth.WebauthAuthServlet</servlet-class>
    <init-param>
      <param-name>reauthURL</param-name>
      <param-value>https://IDP-FQDN/wareauth</param-value>
    </init-param>
    <init-param>
      <param-name>maxTokenAge</param-name>
      <param-value>10</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>WebauthAuthServlet</servlet-name>
    <url-pattern>/Authn/Webauth</url-pattern>
  </servlet-mapping>
(...)
</webapp>

Reauth helper and mod_jk IdP reverse proxy

  • reauth url must be within the same webauth_at context, as we need to be able to delete it from IdP application/module ...
  • j2ee container must be bind behind httpd through mod_jk

Following example has to be placed somewhere in httpd.confs ...


  JkMount /idp/* worker
  JkEnvVar WEBAUTH_USER "<UNSET>"
  JkEnvVar REMOTE_USER "<UNSET>"
  JkEnvVar AUTH_TYPE "<UNSET>"
  JkEnvVar WEBAUTH_TOKEN_CREATION "<UNSET>"
  JkEnvVar WEBAUTH_TOKEN_EXPIRATION "<UNSET>"
  JkEnvVar WEBAUTH_FACTORS_INITIAL "<UNSET>"
  JkEnvVar WEBAUTH_FACTORS_SESSION "<UNSET>"
  JkEnvVar WEBAUTH_LOA "<UNSET>"

<Location /wareauth>
  ## WebAuth     
  AuthType WebAuth
  require valid-user
 
  # WA4
  WebAuthRequireSessionFactor p
  
  RewriteEngine on
  RewriteRule .* https://IDP-FQDN/idp/Authn/Webauth [R,L]
</Location>

Log configuration

The logging for the Handler is configured in the logging.xml file. It can be found at:

  • new install: $IDP_INSTALL_DIR/src/installer/resources/conf-tmpl/logging.xml
  • reinstall: $IDP_DIR/conf/logging.xml
(...)
<logger name="cz.zcu.civ.idp.webauth">
<level value="DEBUG"/>
</logger>
(...)

Deployment

Backup the IdP configuration before re-deploying the application:

$IDP_INSTALL_DIR/install.sh

Known bugs

  • Algorithm is not working if WebKDC clocks skew just behind IdP, authentication failes.
  • If browser is not respecting cookie webauth_at deletion request from server, then it falls in endless redirects, with no auth.

Troubleshooting