Class RequestAuthenticationFilter

java.lang.Object
de.businesscode.bcdui.subjectsettings.services.RequestAuthenticationFilter
All Implemented Interfaces:
jakarta.servlet.Filter

public class RequestAuthenticationFilter extends Object implements jakarta.servlet.Filter
Servlet filter for a trusted backend caller acting on behalf of a BCD-UI user without that user having a browser session - e.g. a bot acting for a user. It expects a trusted caller (a shared secret), and an on-behalf-of identity in the form (idType/onBehalfId), which could, for example, be a phone number. The secret is verified and the identity resolved to a BCD-UI user id by OnBehalfIdentityRealm. The created authorization scope is just the current request: RequestSession, it destroys that session after the request finishes again on close. Pure shiro.ini configuration, just register here and add OnBehalfIdentityRealm to the realm chain:
 bcdRequestAuthentication = de.businesscode.bcdui.subjectsettings.services.RequestAuthenticationFilter
 bcdOnBehalfIdentityRealm = de.businesscode.bcdui.subjectsettings.services.OnBehalfIdentityRealm
 bcdOnBehalfIdentityRealm.trustedClientsSecrets = ##shared-secret-1##, ##shared-secret-n##
 securityManager.realms = ..., $bcdOnBehalfIdentityRealm, ...
 ...
 [urls]
 /bcdui/mcp/** = bcdRequestAuthentication
 
By default a request without the "X-BCD.ClientSecret" header is rejected - this filter is meant to be the sole gate for its path (e.g. /mcp/**, a pure machine-to-machine endpoint). Set setOptional(boolean) to true to instead let such a request fall through to the next filter in the chain unauthenticated by this filter - use this when the same URL must serve both trusted per-request callers and regular interactive browser sessions:
 bcdRequestAuthenticationOptional.optional = true
 ...
 [urls]
 /your/api/** = bcdRequestAuthenticationOptional, bcdAuthc
 
A request presenting the header with a wrong secret is always rejected outright, regardless of optional - a bad/rotated secret must not silently degrade into a normal login attempt.
  • Field Details

  • Constructor Details

    • RequestAuthenticationFilter

      public RequestAuthenticationFilter()
  • Method Details

    • setOptional

      public void setOptional(boolean optional)
      Set from shiro.ini: when true, a request without the "X-BCD.ClientSecret" header is passed through to the next filter in the chain instead of being rejected - use this to let the same URL serve both trusted per-request callers and regular browser sessions (chain this filter ahead of e.g. bcdAuthc on that path). Defaults to false: this filter alone gates its configured path(s) and requires the header.
    • doFilter

      public void doFilter(jakarta.servlet.ServletRequest request, jakarta.servlet.ServletResponse response, jakarta.servlet.FilterChain chain) throws IOException, jakarta.servlet.ServletException
      Specified by:
      doFilter in interface jakarta.servlet.Filter
      Throws:
      IOException
      jakarta.servlet.ServletException
    • createToken

      protected RequestAuthenticationToken createToken(String requestSecret, String idType, String onBehalfId, jakarta.servlet.http.HttpServletRequest request) throws IOException, jakarta.servlet.ServletException
      Extension point to allow subclasses to create a token with additional information. Derive them from request or any properties set in shiro.ini of sub-classes for example
      Parameters:
      requestSecret - provided by trusted(?) caller
      idType - type of user id provided
      onBehalfId - user id of idType to be resolved to userId
      request - maybe important if overwriting this class
      Returns:
      token for OnBehalfIdentityRealm
      Throws:
      IOException
      jakarta.servlet.ServletException