Skip to content

Latest commit

 

History

History
 
 

#AzureAuthenticationFilter This is a proof of concept to provide a Servlet Filter to enable Azure B2C Authentication in a Java Web Application.

This filter handles both Authentication and Authorization. HttpServletRequest.isUserInRole(), HttpServletRequest.getRemoteUser(), and HttpServletRequest.getUserPrincipal() all work as would be expected.

It uses Open ID Connect end-points to obtain:

  • Policy Metadata from the Well Known Configuration end-point
  • The public keys matching the private keys used to sign the tokens from the JWKS end-point specified by the Well Known Configuration end-point
  • Tokens (JWT) from the /authorize end-point specified by the Well Known Configuration end-point

The keys obtained from the JWKS end-point are validated using the "Not Before" attribute, if it exists the keys are marked as invalid if now is before the "Not Before" time-stamp. (if "Not Before" does not exist it is assumed to be valid).

The following validation is performed on tokens returned from the /authorise end-point:

  • "Issued At" is in the past (if it does not exist it is assumed to be valid)
  • "Not Before" is in the past (if it does not exist it is assumed to be valid)
  • "Expiration" is in the future (if it does not exist it is assumed to be valid)
  • "Audience" matches the Application ID configured for the application
  • "Issuer" matches the issuer in the Metadata
  • "Signature" (using a key from the JWKS end-point)

Configuration of this Filter is picked up from system environment variables:

  • AAD_OIDC_POLICY (The policy to use in Open ID Connect)
  • AAD_REDIRECT_URL (The URL to redirect to after obtaining a token)
  • AAD_APPLICATION_ID (The GUID of the application you have registered in Azure AD B2C)
  • AAD_TENANT (The Azure AD B2C tenant to use)
  • AAD_PRINCIPAL_ID (The GUID of the principal used to query the graph API)
  • AAD_PRINCIPAL_SECRET (The password for the principal used to query the graph API)

You will also need to update your web.xml as follows:

<filter>
  <filter-name>authenticationFilter</filter-name>
  <filter-class>com.microsoft.azure.oidc.filter.impl.SimpleAuthenticationFilter</filter-class>
  <init-param>
    <param-name>authenticationConfiguration</param-name>
    <param-value>/WEB-INF/configuration/authentication.json</param-value>
  </init-param>
  <init-param>
    <param-name>algorithmConfiguration</param-name>
     <param-value>/WEB-INF/configuration/algorithm.json</param-value>
  </init-param>
  <init-param>
  	<param-name>securityCacheSize</param-name>
  	<param-value>10000</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>authenticationFilter</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
</filter-mapping>

And add an authentication.json in /WEB-INF/configuration which contains the following:

{
  "exclusionUriPatterns": [
    "/",
    "/index.xhtml",
    "/logout",
    "unauthenticated/*"
  ],
  "authorisationUriPatterns": [
    {"uriPattern": "/authorised.xhtml", "roles": [ "JavaEEManagers", "JavaEEPowerUsers" ]},
    {"uriPattern": "/authorised/*", "roles": [ "JavaEEManagers", "JavaEEPowerUsers" ]}
  ]
}

And add an algorithm.json in /WEB-INF/configuration which contains the following:

{
  "algorithms": [
    {"name": "RS256", "javaName": "SHA256withRSA"},
    {"name": "RS384", "javaName": "SHA384withRSA"},
    {"name": "RS512", "javaName": "SHA512withRSA"}
  ],
  "algorithmClasses": [
    {"name": "RS256", "className": "RSA"},
    {"name": "RS384", "className": "RSA"},
    {"name": "RS512", "className": "RSA"}
  ]
}