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 seconds
  • 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...

For the other factors, at least with the current implementation you can
treat WEBAUTH_SESSION_FACTORS of o as being equivalent to p for your
purposes; those will only be expressed if the user just authenticated with
a one-time password.  x is a little trickier, since in theory that could
mean authenticating with a certificate cached in their browser, which may
not constitute forced authentication for your purposes, but I'd be
inclined to allow it as well.

m and k should not count as authentications for this purpose.

Note that it's theoretically possible (although it won't happen in the
current available code paths) for WEBAUTH_SESSION_FACTORS to be set to
something like p,c,m.  I think that should probably also count as p for
your purposes (and the redirect helper would pass it, so it probably has
to or you'll just get a loop).  This can happen when the user has a single
sign-on cookie that says they authenticated with OTP or some other method
but then you forced password authentication.  So if you're not already,
you probably want to split on comma and then see if p is included, rather
than checking whether the string is exactly equal to p.

These are all minor bits, though.  The basic idea is great.  I didn't look
at the source, but everything seems fine from the description.

-- Russ Allbery <eagle@windlord.stanford.edu>

we will address these issues in the next release ...

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 Authentication module on httpd
  • 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 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 ...

# env variables propagated thgough mod_jk
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>"

# IdP application url binding
JkMount /idp/* worker
<Location /idp/>
  AuthType WebAuth
  require valid-user
</Location>

# reauth helper
<Location /wareauth>
  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