CAS 7.1.4 Proxy Authentication issue

224 views
Skip to first unread message

gautham jampala

unread,
Mar 18, 2025, 2:11:42 PM3/18/25
to CAS Community
Hello,

I'm having issue with proxy authentication when having multiple registered services. We have two registered services one UI components(service_1) and another rest (service_2).
Here is our Login flow:
user tries to access service_1 and is redirected to CAS login
After authentication CAS send PGT to service_1
service-1 requests a PT for service_2 
service_2 validates that PT
service_1 loads the welcome screens in UI and sends rest calls to service_2 from UI to load data.
Here service_2 is being redirected to cas login page
I would expect the CAS to authenticate the user via the session but that does not happen 
As it was a rest call user does not see the login page and he just sees a spinning wheel.
I don't see any exceptions in the logs so any help is appreciated.
Below are my cas properties.
Cas.properties:

cas.server.prefix=https://localhost:8444/cas
cas.view.default-redirect-url=https://localhost:8443
host.name=cas

cas.ticket.st.number-of-uses=1
cas.ticket.st.time-to-kill-in-seconds=2000
cas.ticket.pt.time-to-kill-in-seconds=2000
cas.ticket.tst.time-to-kill-in-seconds=3000
cas.ticket.tgt.primary.time-to-kill-in-seconds=PT2H

cas.http-client.allow-local-urls=true

cas.service-registry.yaml.location=file://${user.home}/

cas.logout.redirectUrl=https://localhost:8443


logging.config=${user.home}/log4j2.xml


####
#########################################################################
# LDAP Authentication
#
cas.authn.ldap[0].type=AUTHENTICATED
cas.authn.ldap[0].ldapUrl=ldap://localhost:10389
cas.authn.ldap[0].baseDn=dc=lawbulletin,dc=com
cas.authn.ldap[0].searchFilter=mail={user}
cas.authn.ldap[0].bindDn=uid=admin,ou=system
cas.authn.ldap[0].bindCredential=*******
cas.authn.ldap[0].principalAttributeList=memberOf,mail,givenName,mobile

# LDAP connection pooling
cas.authn.ldap[0].minPoolSize=3
cas.authn.ldap[0].maxPoolSize=10
cas.authn.ldap[0].connectTimeout=PT3S
cas.authn.ldap[0].responseTimeout=PT3S
cas.authn.ldap[0].blockWaitTime=PT10S

# == Evictor configuration ==
cas.authn.ldap[0].validatePeriod=PT10M
cas.authn.ldap[0].idleTime=PT20M

# == Connection testing settings ==
cas.authn.ldap[0].validatePeriodically=true
cas.authn.ldap[0].validateOnCheckout=false

cas.custom.properties.logoutRedirectUrl=https://localhost:8443

cas.httpWebRequest.header.xframe=false
cas.httpWebRequest.header.xss=false
cas.httpWebRequest.header.xcontent=false

# Disable default CAS user
cas.authn.accept.users=
cas.authn.accept.name=

cas.authn.token.crypto.encryption.key-size=512
cas.authn.token.crypto.signing.key-size=512

# Ticket registry
cas.ticket.registry.jpa.driver-class=com.mysql.cj.jdbc.Driver
cas.ticket.registry.jpa.enabled=true
cas.ticket.registry.jpa.password=********
cas.ticket.registry.jpa.url=jdbc:mysql://localhost:3306/DM_COMM
cas.ticket.registry.jpa.user==********
cas.ticket.registry.jpa.ddl-auto=update
cas.ticket.registry.jpa.dialect=org.hibernate.dialect.MySQLDialect
cas.ticket.registry.jpa.properties.hibernate.dialect.storage_engine=innodb

#mail server
spring.mail.host=localhost
spring.mail.port=25000
spring.mail.testConnection=true


#email MFA config
cas.authn.mfa.simple.mail.from=exm...@example.com
cas.authn.mfa.simple.mail.subject= Your Requested One-Time Password
cas.authn.mfa.simple.mail.text=file:/${user.home}/emailTemplate.html
cas.authn.mfa.simple.mail.html=true
cas.authn.mfa.simple.mail.attributeName=mail
cas.authn.mfa.simple.token.core.time-to-kill-in-seconds=300


#GoogleAuth config
cas.authn.mfa.gauth.core.issuer=CAS
cas.authn.mfa.gauth.core.label=CASLabel
cas.authn.mfa.triggers.principal.globalPrincipalAttributeNameTriggers=memberOf
cas.authn.mfa.triggers.principal.globalPrincipalAttributeValueRegex=mfa-*
cas.authn.mfa.gauth.bypass.groovy.location=file:/${user.home}/MultifactorBypass.groovy
cas.authn.mfa.simple.bypass.groovy.location=file:/${user.home}/MultifactorBypass.groovy

#Googlle auth JPA config
cas.authn.mfa.gauth.jpa.driver-class=com.mysql.cj.jdbc.Driver
cas.authn.mfa.gauth.jpa.password=*******
cas.authn.mfa.gauth.jpa.url=jdbc:mysql://localhost/DM_COMM
cas.authn.mfa.gauth.jpa.user=*******
cas.authn.mfa.gauth.jpa.ddl-auto=update
cas.authn.mfa.gauth.jpa.dialect=org.hibernate.dialect.MySQLDialect
cas.authn.mfa.gauth.jpa.properties.hibernate.dialect.storage_engine=innodb


cas.webflow.crypto.signing.key=bCECvhcSh3VunipcsaYT2PUKfeLSkJ59tn4MY24xEdq_iRwlRsoq6y3qVPlGo6JwVV0t2bVM2FZAOHXXG0-ZRg
cas.webflow.crypto.encryption.key=VSiHJNQG67-Xcj4Ak6XR_w
cas.authn.mfa.gauth.crypto.encryption.key=toVy_ktn9mxuh1idt5n-kH59KyCezX3wajaIbOmqd0c
cas.authn.mfa.gauth.crypto.signing.key=_yVTQn_7vQbSaIG1XF3mZ9wQ9EPOOJJC5mPUDSzpmnKwxxrwCa1rMtrcPVtzlKEErWtbA8vGq3hy-ukd5mJw6Q


cas.authn.mfa.simple.bucket4j.enabled=true
cas.authn.mfa.simple.bucket4j.blocking=true

cas.authn.mfa.simple.bucket4j.bandwidth[0].capacity=20
cas.authn.mfa.simple.bucket4j.bandwidth[0].duration=PT1M

cas.authn.mfa.simple.bucket4j.bandwidth[1].capacity=5
cas.authn.mfa.simple.bucket4j.bandwidth[1].duration=PT5S

cas.authn.pac4j.webflow.enabled=true
cas.authn.pac4j.core.discovery-selection.selection-type=DYNAMIC

#Delegated Authentication 
cas.authn.pac4j.oidc[0].azure.tenant=*******
cas.authn.pac4j.oidc[0].azure.discovery-uri=https://login.microsoftonline.com/${cas.authn.pac4j.oidc[0].azure.tenant}/v2.0/.well-known/openid-configuration
cas.authn.pac4j.oidc[0].azure.id=*******
cas.authn.pac4j.oidc[0].azure.secret=*******
cas.authn.pac4j.oidc[0].azure.auto-redirect-type=NONE
cas.authn.pac4j.oidc[0].azure.client-name=AzureClient
cas.authn.pac4j.oidc[0].azure.scope=openid,profile,email
cas.authn.pac4j.oidc[0].azure.principal-id-attribute=email
cas.authn.pac4j.oidc[0].azure.css-class=
cas.authn.pac4j.oidc[0].azure.logout-url=https://login.microsoftonline.com/${cas.authn.pac4j.oidc[0].azure.tenant}/v2.0/logout
cas.authn.pac4j.oidc[0].azure.preferred-jws-algorithm=RS512


cas.authn.policy.any.enabled=true

#json rules files defining which domain name currespondes to which IDP
cas.authn.pac4j.core.discovery-selection.json.location=file:/${user.home}/emailToIDPMappingRules.json
screen.pac4j.button.selectprovider=SSO Login

# Set SameSite policy for cross-domain authentication
cas.session-replication.cookie.same-site-policy=LAX

# Ensure the cookie is only sent over HTTPS (I was experimenting with below setting to see if that solves the issue)
cas.session-replication.cookie.secure=true
cas.sso.proxy-authn-enabled=true
cas.sso.sso-enabled=true
cas.tgc.secure=false
cas.tgc.same-site-policy=LAX
cas.tgc.max-age=-1
cas.tgc.remember-me-max-age=P14D
cas.tgc.http-only=false
cas.tgc.crypto.encryption.key=PqN1lyOIrdCppLN0MaORzkBFDuaS4ytKWmBgRYVhjwI
cas.tgc.crypto.signing.key=4eWRTqk5RCP97v96pY0Ear6HdTX6kYbNoe32k8nEZjRCDFjXoMzQG3zdEg1fsxpEJL9gGHq7AlOkIp2htvn9Eg
cas.tgc.crypto.alg=A256GCM
cas.tgc.crypto.encryption.key-size=256

#disable caching of html fragments
spring.thymeleaf.cache=false
cas.view.template-prefixes=classpath:templates,file:/templates

cas.ticket.registry.core.enable-locking=false
cas.http-client.allow-local-urls=true

cas.http-web-request.cors.enabled=true
cas.http-web-request.cors.allow-credentials=true
cas.http-web-request.cors.allow-methods=*
cas.http-web-request.cors.allow-headers=*
cas.http-web-request.cors.allow-origin-patterns=https://localhost:8443*

service_1.yml:
--- !<org.apereo.cas.services.CasRegisteredService>
serviceId: "https://localhost:8443/service1/.*"
name: "service1"
id: 1
description: "CAS config for service1"
evaluationOrder : 100
authenticationPolicy: !<org.apereo.cas.services.DefaultRegisteredServiceAuthenticationPolicy>
  criteria: !<org.apereo.cas.services.AnyAuthenticationHandlerRegisteredServiceAuthenticationPolicyCriteria>
    tryAll: false
proxyPolicy: !<org.apereo.cas.services.RegexMatchingRegisteredServiceProxyPolicy>
  pattern: "^https://localhost:8443/.*"
accessStrategy: !<org.apereo.cas.services.DefaultRegisteredServiceAccessStrategy>
  enabled: true
  ssoEnabled: true
matchingStrategy: !<org.apereo.cas.services.FullRegexRegisteredServiceMatchingStrategy>

service_2.yml:
--- !<org.apereo.cas.services.CasRegisteredService>
serviceId: "https://localhost:8443/service2/.*"
name: "Service2"
id: 2
description: "CAS config for Service2"
logoutUrl: "https://localhost:8443/service2/logout"
logoutType: "FRONT_CHANNEL"
evaluationOrder : 200
proxyPolicy: !<org.apereo.cas.services.RegexMatchingRegisteredServiceProxyPolicy>
  pattern: "^https://localhost:8443/.*"
authenticationPolicy: !<org.apereo.cas.services.DefaultRegisteredServiceAuthenticationPolicy>
  criteria: !<org.apereo.cas.services.AnyAuthenticationHandlerRegisteredServiceAuthenticationPolicyCriteria>
    tryAll: false
accessStrategy: !<org.apereo.cas.services.DefaultRegisteredServiceAccessStrategy>
  enabled: true
  ssoEnabled: true
matchingStrategy: !<org.apereo.cas.services.FullRegexRegisteredServiceMatchingStrategy>

Thank you,
Gautham

Ray Bon

unread,
Mar 18, 2025, 11:16:46 PM3/18/25
to cas-...@apereo.org
Gautham,

service_2 will need a PT for every call from service_1. The same PT could be reused; depends on your config, https://apereo.github.io/cas/7.1.x/ticketing/Configuring-Ticket-Expiration-Policy-PT.html

The user authentication is tracked in the browser with a TGC (linked to a TGT on the cas server). service_1 has a PGT linked to the same TGT. The PGT is independent of the user's browser session TGC. service_2 has no persistent session identifier (from the cas point of view), so this is why a PT must be sent with each call.

Ray

On Tue, 2025-03-18 at 10:40 -0700, gautham jampala wrote:
You don't often get email from gauta...@gmail.com. Learn why this is important
Reply all
Reply to author
Forward
0 new messages