I seem to have missed something, but I can't find what is wrong with my configuration.
A brief explanation first, the config files and the full log later.
My problem is that I can't authenticate against the Azure AD - when the process is transforming the credential username it gets null as transformed username:
Couple of log clips
After restart of Tomcat, I got these
INFO [org.apereo.cas.web.CasWebApplicationServletInitializer] - <Started CasWebApplicationServletInitializer in 24.503 seconds (JVM running for 33.461)>
INFO [org.apereo.cas.services.AbstractServicesManager] - <Loaded [0] service(s) from [JsonServiceRegistry].>
Am I missing something or is that OK?
When I load the cas/login page: these two messages pop out from the stream of debug messages - have I missed something or is this normal?
DEBUG [org.apereo.cas.web.flow.resolver.impl.RankedMultifactorAuthenticationProviderWebflowEventResolver] - <No service is available to determine event for principal>
DEBUG [org.apereo.cas.web.flow.resolver.impl.AbstractCasWebflowEventResolver] - <Resolved single event [success] via [org.apereo.cas.web.flow.resolver.impl.RankedMultifactorAuthenticationProviderWebflowEventResolver] for this context>
Once I fill in the username and password and click submit I get: Your account is not recognized and cannot login at this time.
These lines caught my attention from the log
DEBUG [org.apereo.cas.authentication.DefaultAuthenticationManager] - <Attempting authentication of [testusername] using [casad]>
DEBUG [org.apereo.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler] - <Transforming credential username via [org.apereo.cas.util.transforms.ChainingPrincipalNameTransformer]>
INFO [org.apereo.cas.authentication.DefaultAuthenticationManager] - <[casad] exception details: [Transformed username is null.].>
The CAS WAR overlay template project is bootstrapped and generated via the CAS Initializr.
getcas --modules support-reports,support-azuread-authentication,webapp-tomcat --casVersion 6.6.14
The contents of /etc/cas/config/cas.properties:
#
cas.server.name=
https://localhost:8080cas.server.prefix=${
cas.server.name}/cas
logging.config=file:/etc/cas/config/log4j2.xml
##########################################
#Let's keep it secure
cas.authn.accept.users=
######################################
#Cas running as embedded Apache Tomcat container and Apache terminates SSL connections as a proxy...
server.port=8080
server.ssl.enabled=false
cas.server.tomcat.http[0].enabled=false
cas.server.tomcat.httpProxy.enabled=true
cas.server.tomcat.httpProxy.secure=true
cas.server.tomcat.httpProxy.scheme=https
#
# Crypto
#
cas.tgc.crypto.encryption.key=<xxx>
cas.tgc.crypto.signing.key=<xxx>
cas.webflow.crypto.signing.key=<xxx>
cas.webflow.crypto.encryption.key=<xxx>
## tests
cas.authn.policy.source-selection-enabled=true
#CAS azure active dir
cas.authn.azure-active-directory.name=casad
cas.authn.azure-active-directory.login-url=
https://login.microsoftonline.com/common/cas.authn.azure-active-directory.client-id=<xxx>
#cas.authn.azure-active-directory.principal-transformation.suffix=@<xxx>.
onmicrosoft.comcas.authn.azure-active-directory.password-encoder.encoding-algorithm=SHA-512
cas.authn.azure-active-directory.password-encoder.type=DEFAULT
cas.authn.azure-active-directory.principal-transformation.groovy.location=/etc/cas/groovy/principaltransform.groovy
cas.authn.attribute-repository.azure-active-directory[0].client-id=<xxx>
cas.authn.attribute-repository.azure-active-directory[0].client-secret=<xxx>
cas.authn.attribute-repository.azure-active-directory[0].tenant=<xxx>
# Management endpoints
management.endpoints.web.base-path=/actuator
management.endpoints.web.exposure.include=info,health,metrics
management.endpoint.info.enabled=true
management.endpoint.health.enabled=true
management.endpoint.metrics.enabled=true
cas.monitor.endpoints.endpoint.info.access=AUTHENTICATED
cas.monitor.endpoints.endpoint.health.access=AUTHENTICATED
cas.monitor.endpoints.endpoint.metrics.access=AUTHENTICATED
spring.security.user.name=<xxx>
spring.security.user.password=<xxx>
The contents of /etc/cas/groovy/principaltransform.groovy:
// Sample Groovy script for principal transformation with Azure AD
//
import org.apereo.cas.authentication.principal.Principal
// Method to perform the transformation
def Principal transformPrincipal(Principal principal) {
// Print the original principal for reference
// println("Original Principal: $principal")
// Get the attributes of the principal
def attributes = principal.getAttributes()
// Assuming 'displayName' is an attribute returned by Azure AD
// def displayName = attributes['displayName']
// Modify or add attributes as needed
attributes['username'] = attributes['preferred_username']
//attributes['displayName'] = displayName.toUpperCase()
// Create a new principal with the updated attributes
def updatedPrincipal = new Principal(principal.getId(), attributes)
// Print the updated principal for reference
//println("Updated Principal: $updatedPrincipal")
// Return the updated principal
return updatedPrincipal
}
// Call the transformation method
transformPrincipal(principal)
The full log form tomcat start:
2023-12-03 17:37:49,214 INFO [org.apereo.cas.configuration.CasConfigurationPropertiesValidator] - <Validated CAS property sources and configuration successfully.>
_ ____ _____ ____ _____ ___ ____ _ ____
/ \ | _ \| ____| _ \| ____/ _ \ / ___| / \ / ___|
/ _ \ | |_) | _| | |_) | _|| | | | | | / _ \ \___ \
/ ___ \| __/| |___| _ <| |__| |_| | | |___ / ___ \ ___) |
/_/ \_\_| |_____|_| \_\_____\___/ \____/_/ \_\____/
CAS Version: 6.6.14
CAS Branch: 6.6.x
CAS Commit Id: d6a6b87d017726693ad155d56d55e90368ceec71
CAS Build Date/Time: 2023-11-20T12:33:32Z
Spring Boot Version: 2.7.3
Spring Version: 5.3.22
Java Home: /usr/lib/jvm/java-11-openjdk-amd64
Java Vendor: Ubuntu
Java Version: 11.0.21
JVM Free Memory: 394 MB
JVM Maximum Memory: 910 MB
JVM Total Memory: 640 MB
OS Architecture: amd64
OS Name: Linux
OS Version: 5.15.0-89-generic
OS Date/Time: 2023-12-03T17:37:53.173827
OS Temp Directory: /opt/tomcat/current//temp
------------------------------------------------------------
Apache Tomcat Version: Apache Tomcat/9.0.83
------------------------------------------------------------
INFO [org.apereo.cas.configuration.DefaultCasConfigurationPropertiesSourceLocator] - <Configuration files found at [/etc/cas/config] are [[file [/etc/cas/config/cas.properties]]] under profile(s) [[standalone]]>
INFO [org.apereo.cas.configuration.CasConfigurationPropertiesValidator] - <Validated CAS property sources and configuration successfully.>
INFO [org.apereo.cas.web.CasWebApplicationServletInitializer] - <The following 1 profile is active: "standalone">
INFO [org.apereo.cas.services.resource.AbstractResourceBasedServiceRegistry] - <Watching service registry directory at [/opt/tomcat/apache-tomcat-9.0.83/temp/services]>
INFO [org.apereo.cas.util.io.PathWatcherService] - <Watching directory path at [/opt/tomcat/apache-tomcat-9.0.83/temp/services]>
DEBUG [org.apereo.cas.tomcat.CasTomcatServletWebServerFactoryCustomizer] - <Customizing HTTP proxying for connector listening on port [8080]>
DEBUG [org.apereo.cas.web.security.CasWebSecurityConfigurerAdapter] - <Configuring protocol endpoints [[/login/**, /logout/**, /validate/**, /serviceValidate/**, /p3/serviceValidate/**, /proxyValidate/**, /p3/proxyValidate/**, /proxy/**, /webjars/**, /js/**, /css/**, /images/**, /static/**, /error, /favicon.ico]] to exclude/ignore from web security>
DEBUG [org.apereo.cas.monitor.config.CasCoreMonitorConfiguration] - <Configured memory monitor with free-memory threshold [10]>
DEBUG [org.apereo.cas.web.security.CasWebSecurityConfigurerAdapter] - <Configuring protocol endpoints [[/login/**, /logout/**, /validate/**, /serviceValidate/**, /p3/serviceValidate/**, /proxyValidate/**, /p3/proxyValidate/**, /proxy/**, /webjars/**, /js/**, /css/**, /images/**, /static/**, /error, /favicon.ico]] to exclude/ignore from web security>
INFO [org.apereo.cas.config.CasCoreTicketsConfiguration] - <Runtime memory is used as the persistence storage for retrieving and managing tickets. Tickets that are issued during runtime will be LOST when the web server is restarted. This MAY impact SSO functionality.>
INFO [org.apereo.cas.util.CoreTicketUtils] - <Ticket registry encryption/signing is turned off. This MAY NOT be safe in a clustered production environment. Consider using other choices to handle encryption, signing and verification of ticket registry tickets, and verify the chosen ticket registry does support this behavior.>
DEBUG [org.apereo.cas.authentication.support.password.PasswordEncoderUtils] - <Creating default password encoder with encoding alg [SHA-512] and character encoding [UTF-8]>
DEBUG [org.apereo.cas.config.CasPersonDirectoryConfiguration] - <Configured attribute repository sources to merge together: [[MicrosoftGraphPersonAttributeDao]]>
DEBUG [org.apereo.cas.util.cipher.BaseStringCipherExecutor] - <Using pre-defined encryption key to use for [cas.tgc.crypto.encryption.key]>
DEBUG [org.apereo.cas.util.cipher.BaseStringCipherExecutor] - <Using pre-defined signing key to use for [cas.tgc.crypto.signing.key]>
DEBUG [org.apereo.cas.config.CasCoreTicketsSchedulingConfiguration] - <Ticket registry cleaner is enabled.>
DEBUG [org.apereo.cas.pm.config.PasswordManagementConfiguration] - <Password management is disabled. To enable the password management functionality, add 'cas.authn.pm.core.enabled=true' to the CAS configuration and then configure storage options for account updates>
INFO [org.apereo.cas.web.CasWebApplicationServletInitializer] - <Started CasWebApplicationServletInitializer in 24.835 seconds (JVM running for 33.7)>
INFO [org.apereo.cas.services.AbstractServicesManager] - <Loaded [0] service(s) from [JsonServiceRegistry].>
INFO [org.apereo.cas.web.CasWebApplicationReady] - <>
INFO [org.apereo.cas.web.CasWebApplicationReady] - <
____ _____ _ ______ __
| _ \| ____| / \ | _ \ \ / /
| |_) | _| / _ \ | | | \ V /
| _ <| |___ / ___ \| |_| || |
|_| \_\_____/_/ \_\____/ |_|
>
INFO [org.apereo.cas.web.CasWebApplicationReady] - <>
INFO [org.apereo.cas.web.CasWebApplicationReady] - <Ready to process requests @ [<timestamp here>]>
INFO [org.apereo.cas.services.AbstractServicesManager] - <Loaded [0] service(s) from [JsonServiceRegistry].>
INFO [org.apereo.cas.ticket.registry.DefaultTicketRegistryCleaner] - <[0] expired tickets removed.>
INFO [org.apereo.cas.services.AbstractServicesManager] - <Loaded [0] service(s) from [JsonServiceRegistry].>
INFO [org.apereo.cas.services.AbstractServicesManager] - <Loaded [0] service(s) from [JsonServiceRegistry].>
INFO [org.apereo.cas.ticket.registry.DefaultTicketRegistryCleaner] - <[0] expired tickets removed.>
The authentication page is requested:
DEBUG [org.apereo.cas.web.flow.CasFlowHandlerMapping] - <Mapped to [FlowHandlerMapping.DefaultFlowHandler@4c619c6e]>
WARNING [ajp-nio-127.0.0.1-8009-exec-2] javax.persistence.spi.PersistenceProviderResolverHolder$DefaultPersistenceProviderResolver.log javax.persistence.spi::No valid providers found.
DEBUG [org.apereo.cas.web.flow.login.InitialFlowSetupAction] - <Setting path for cookies for warn cookie generator to: [/cas/]>
DEBUG [org.apereo.cas.web.flow.login.InitialFlowSetupAction] - <Setting path for cookies for TGC cookie generator to: [/cas/]>
DEBUG [org.apereo.cas.web.flow.resolver.impl.RankedMultifactorAuthenticationProviderWebflowEventResolver] - <No service is available to determine event for principal>
DEBUG [org.apereo.cas.web.flow.resolver.impl.AbstractCasWebflowEventResolver] - <Resolved single event [success] via [org.apereo.cas.web.flow.resolver.impl.RankedMultifactorAuthenticationProviderWebflowEventResolver] for this context>
DEBUG [org.apereo.cas.services.web.DefaultCasThemeSource] - <Theme created: name 'cas-theme-default', basename [cas-theme-default]>
DEBUG [org.apereo.cas.web.view.CasReloadableMessageBundle] - <No properties file found for [file:/etc/cas/config/custom_messages_en] - neither plain properties nor XML>
DEBUG [org.apereo.cas.web.view.CasReloadableMessageBundle] - <No properties file found for [file:/etc/cas/config/custom_messages] - neither plain properties nor XML>
DEBUG [org.apereo.cas.web.view.CasReloadableMessageBundle] - <No properties file found for [classpath:custom_messages_en] - neither plain properties nor XML>
DEBUG [org.apereo.cas.web.view.CasReloadableMessageBundle] - <No properties file found for [classpath:custom_messages] - neither plain properties nor XML>
DEBUG [org.apereo.cas.web.view.CasReloadableMessageBundle] - <No properties file found for [classpath:messages_en] - neither plain properties nor XML>
DEBUG [org.apereo.cas.web.view.CasReloadableMessageBundle] - <Loading properties [messages.properties] with encoding 'UTF-8'>
Once the authentication is attempted:
DEBUG [org.apereo.cas.web.flow.CasFlowHandlerMapping] - <Mapped to [FlowHandlerMapping.DefaultFlowHandler@7e7c60d7]>
DEBUG [org.apereo.cas.authentication.adaptive.DefaultAdaptiveAuthenticationPolicy] - <User agent [Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0] is authorized to proceed>
DEBUG [org.apereo.cas.authentication.adaptive.DefaultAdaptiveAuthenticationPolicy] - <Adaptive authentication policy has authorized client [IP address here] to proceed.>
DEBUG [org.apereo.cas.web.flow.resolver.impl.ServiceTicketRequestWebflowEventResolver] - <Request is not eligible to be issued service tickets just yet>
DEBUG [org.apereo.cas.authentication.DefaultAuthenticationManager] - <Authentication credentials provided for this transaction are [[UsernamePasswordCredential(username=testusername, source=Casad, customFields={})]]>
DEBUG [org.apereo.cas.authentication.DefaultAuthenticationEventExecutionPlan] - <Candidate/Registered authentication handlers for this transaction are [[org.apereo.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler@634010c, org.apereo.cas.azure.ad.authentication.AzureActiveDirectoryAuthenticationHandler@3949b25b]]>
DEBUG [org.apereo.cas.authentication.DefaultAuthenticationEventExecutionPlan] - <Authentication handler resolvers for this transaction are [[org.apereo.cas.authentication.handler.ByCredentialSourceAuthenticationHandlerResolver@ff178c3, org.apereo.cas.authentication.AuthenticationHandlerResolver$1@1127ccf8, org.apereo.cas.authentication.handler.RegisteredServiceAuthenticationHandlerResolver@6ab25364]]>
DEBUG [org.apereo.cas.authentication.handler.ByCredentialSourceAuthenticationHandlerResolver] - <Evaluating authentication handler [casad] for eligibility>
DEBUG [org.apereo.cas.authentication.handler.ByCredentialSourceAuthenticationHandlerResolver] - <Comparing credential source [Casad] against authentication handler [casad]>
2023-12-03 17:25:23,332 DEBUG [org.apereo.cas.authentication.DefaultAuthenticationEventExecutionPlan] - <Resolved and finalized authentication handlers to carry out this authentication transaction are [[org.apereo.cas.authentication.handler.ByCredentialSourceAuthenticationHandlerResolver@ff178c3, org.apereo.cas.authentication.AuthenticationHandlerResolver$1@1127ccf8, org.apereo.cas.authentication.handler.RegisteredServiceAuthenticationHandlerResolver@6ab25364]]>
DEBUG [org.apereo.cas.authentication.DefaultAuthenticationManager] - <Candidate resolved authentication handlers for this transaction are [[org.apereo.cas.azure.ad.authentication.AzureActiveDirectoryAuthenticationHandler@3949b25b]]>
DEBUG [org.apereo.cas.authentication.DefaultAuthenticationManager] - <Attempting to authenticate credential [UsernamePasswordCredential(username=testusername, source=Casad, customFields={})]>
DEBUG [org.apereo.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler] - <Examining credential [UsernamePasswordCredential(username=testusername, source=Casad, customFields={})] eligibility for authentication handler [casad]>
DEBUG [org.apereo.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler] - <Credential [UsernamePasswordCredential(username=testusername, source=Casad, customFields={})] eligibility is [casad] for authentication handler [true]>
DEBUG [org.apereo.cas.authentication.DefaultAuthenticationManager] - <Attempting authentication of [testusername] using [casad]>
DEBUG [org.apereo.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler] - <Transforming credential username via [org.apereo.cas.util.transforms.ChainingPrincipalNameTransformer]>
INFO [org.apereo.cas.authentication.DefaultAuthenticationManager] - <[casad] exception details: [Transformed username is null.].>
DEBUG [org.apereo.cas.authentication.DefaultAuthenticationEventExecutionPlan] - <Authentication policy resolvers for this transaction are [[org.apereo.cas.authentication.policy.RegisteredServiceAuthenticationPolicyResolver@bf09df3]]>
DEBUG [org.apereo.cas.authentication.DefaultAuthenticationEventExecutionPlan] - <Authentication policy resolvers produced no candidate authentication policy. Using default policies>
DEBUG [org.apereo.cas.web.flow.resolver.impl.DefaultCasDelegatingWebflowEventResolver] - <1 errors, 0 successes>
DEBUG [org.apereo.cas.web.flow.resolver.impl.DefaultCasDelegatingWebflowEventResolver] - <Authentication request failed with [401], resulting in event [authenticationFailure]>
DEBUG [org.apereo.cas.web.flow.resolver.impl.AbstractCasWebflowEventResolver] - <Resolved single event [authenticationFailure] via [org.apereo.cas.web.flow.resolver.impl.DefaultCasDelegatingWebflowEventResolver] for this context>
WARNING [ajp-nio-127.0.0.1-8009-exec-3] javax.persistence.spi.PersistenceProviderResolverHolder$DefaultPersistenceProviderResolver.log javax.persistence.spi::No valid providers found.
DEBUG [org.apereo.cas.web.flow.actions.AuthenticationExceptionHandlerAction] - <Located current event [authenticationFailure]>
DEBUG [org.apereo.cas.web.flow.actions.AuthenticationExceptionHandlerAction] - <Located error attribute [class org.apereo.cas.authentication.AuthenticationException] with message [1 errors, 0 successes] from the current event>
DEBUG [org.apereo.cas.web.view.CasReloadableMessageBundle] - <No properties file found for [file:/etc/cas/config/custom_messages_en] - neither plain properties nor XML>
DEBUG [org.apereo.cas.web.view.CasReloadableMessageBundle] - <No properties file found for [file:/etc/cas/config/custom_messages] - neither plain properties nor XML>
DEBUG [org.apereo.cas.web.view.CasReloadableMessageBundle] - <No properties file found for [classpath:custom_messages_en] - neither plain properties nor XML>
DEBUG [org.apereo.cas.web.view.CasReloadableMessageBundle] - <No properties file found for [classpath:custom_messages] - neither plain properties nor XML>
DEBUG [org.apereo.cas.web.view.CasReloadableMessageBundle] - <No properties file found for [classpath:messages_en] - neither plain properties nor XML>
DEBUG [org.apereo.cas.web.view.CasReloadableMessageBundle] - <Re-caching properties for filename [classpath:messages] - file hasn't been modified>
DEBUG [org.apereo.cas.web.flow.actions.AuthenticationExceptionHandlerAction] - <Final event id resolved from the error is [AccountNotFoundException]>
INFO [org.apereo.cas.services.AbstractServicesManager] - <Loaded [0] service(s) from [JsonServiceRegistry].>
This
message and its attachments are private and confidential. If you have received
this message in error, please notify the sender and remove it and its
attachments from your system.
The University of Westminster is a charity and a company limited by guarantee. Registration number: 977818 England. Registered Office: 309 Regent Street, London W1B 2UW.