0

我正在尝试将 Apereo CAS 5.3.16 设置为使用 SAML2 IdP 和 JDBC (PostreSQL) 数据库 IdP。我们需要 CAS 尝试首先针对 SAML IdP 进行身份验证,然后,如果失败,则针对 JDBC IdP。

不幸的是,在过去的周末,v 5.3.16 的文档已从 Apereo 网站上删除,所以现在我正在使用代码库中的降价源文档。我已经广泛查阅了手册并阅读了这些帖子 - https://fawnoos.com/2017/03/22/cas51-delauthn-tutorial/CAS 将身份验证委托给 Azure SAML - 并且无法让应用程序执行我们的操作需要。

CAS 创建其 SAML 元数据、密钥并从 SAML IdP (Okta) 获取元数据。

日志显示以下条目:

DEBUG [org.apereo.cas.authentication.PolicyBasedAuthenticationManager] - 
<Resolved and finalized authentication handlers to carry out this authentication transaction are
[[org.apereo.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler@301ed37a, 
org.apereo.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler@b48d4df,
org.apereo.cas.support.pac4j.authentication.handler.support.ClientAuthenticationHandler@6d3bc620]

这对我来说是正确的,除了我希望 pac4j 处理程序在 JDBC 处理程序之前执行。我不知道它是什么HttpBasedServiceCredentialsAuthenticationHandler,但它是其源代码中 CAS 核心的一部分,所以我认为它应该在那里。

身份验证请求首先发送到 JDBC 处理程序,如果失败,则不会发送到 SAML 处理程序。认证请求立即被拒绝。

这是我们的属性文件(standalone.properties)的(相关部分)。

某个善良的灵魂可以告诉我我错过了什么或做错了什么吗?

# --- UTS Library --- #
server.port=8080
server.ssl.enabled=false
server.use-forward-headers=true
server.session.cookie.http-only=true
server.session.tracking-modes=cookie

cas.server.name=${CAS_SERVER_NAME:}
cas.server.prefix=${cas.server.name}/cas
cas.host.name=

# Default theme name
cas.theme.defaultThemeName=ourtheme

# CAS session persistence
cas.ticket.tgt.rememberMe.enabled=true
cas.ticket.tgt.rememberMe.timeToKillInSeconds=604800

##
# CAS endpoint security
#

...


# logging settings
# Stacktrace settings, possible values: NEVER|ALWAYS|ON_TRACE_PARAM
server.error.include-stacktrace=${CAS_INCLUDE_STACKTRACE:ALWAYS}

##
# Database settings
#
database.driverClass=org.postgresql.Driver
database.url=jdbc:postgresql://${CAS_DB_HOST:127.0.0.1}:${CAS_DB_PORT:5432}/${CAS_DB_NAME:our_db}
database.dialect=org.hibernate.dialect.PostgreSQL82Dialect
database.user=${CAS_DB_USER:}
database.password=${CAS_DB_PASS:}
database.pool.initialSize=2
database.pool.minSize=2
database.pool.maxSize=12
database.pool.acquireIncrement=2
# kills persistent connections that have been idle for > 60 seconds
database.pool.maxIdleTime=60

# keys
cas.tgc.crypto.encryption.key=${CAS_TGC_ENCRYPTION_KEY:}
cas.tgc.crypto.signing.key=${CAS_TGC_SIGNING_KEY:}
cas.webflow.crypto.encryption.key=${CAS_WEBFLOW_ENCRYPTION_KEY:}
cas.webflow.crypto.signing.key=${CAS_WEBFLOW_SIGNING_KEY:}

##
# CAS Authentication Policy
#
cas.authn.policy.any.enabled=true
cas.authn.policy.any.tryAll=false

# Attribute release policy
cas.authn.attributeRepository.defaultAttributesToRelease=username,givenname,familyname,mail,[others]

# Disable default authenticators
cas.authn.accept.users=
#cas.sso.proxyAuthnEnabled=false

##
# Okta SAML IdP delegation integration
cas.authn.pac4j.saml[0].keystorePassword=our_passwd
cas.authn.pac4j.saml[0].privateKeyPassword=our_key
cas.authn.pac4j.saml[0].serviceProviderEntityId=urn:cas:saml:our.url
cas.authn.pac4j.saml[0].serviceProviderMetadataPath=/etc/cas/config/sp-metadata.xml
cas.authn.pac4j.saml[0].keystorePath=/etc/cas/config/samlKeystore.jks
cas.authn.pac4j.saml[0].identityProviderMetadataPath=https://our.okta.vanity.domain/app/our_okta_sp_id/sso/saml/metadata

## 
# PostgreSQL authentication
cas.authn.jdbc.query[0].name=ourdb
cas.authn.jdbc.query[0].order=1
cas.authn.jdbc.query[0].sql=SELECT ...
cas.authn.jdbc.query[0].fieldPassword=password
cas.authn.jdbc.query[0].fieldDisabled=disabled
cas.authn.jdbc.query[0].url=${database.url}
cas.authn.jdbc.query[0].dialect=${database.dialect}
cas.authn.jdbc.query[0].user=${database.user}
cas.authn.jdbc.query[0].password=${database.password}
cas.authn.jdbc.query[0].driverClass=${database.driverClass}
cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=...

##
# Attributes
#
cas.authn.attributeRepository.jdbc[0].sql=SELECT ...
cas.authn.attributeRepository.jdbc[0].username=username,univid
...
cas.authn.attributeRepository.jdbc[0].singleRow=true
cas.authn.attributeRepository.jdbc[0].order=0
cas.authn.attributeRepository.jdbc[0].queryType=OR
cas.authn.attributeRepository.jdbc[0].url=${database.url}
cas.authn.attributeRepository.jdbc[0].dialect=${database.dialect}
cas.authn.attributeRepository.jdbc[0].user=${database.user}
cas.authn.attributeRepository.jdbc[0].password=${database.password}
cas.authn.attributeRepository.jdbc[0].driverClass=${database.driverClass}

# Specify whether CAS should redirect to the specified service parameter on /logout requests
cas.logout.followServiceRedirects=true

# Specify how CAS should respond and validate incoming HTTP requests
# X-Frame-Options - default setting is DENY
cas.httpWebRequest.header.xframe=true
cas.httpWebRequest.header.xframeOptions=ALLOWALL

##
# CAS PersonDirectory Principal Resolution
#
...

##
# CAS Authentication Throttling
#
...

##
# CAS Health Monitoring
#
...

##
# SAML
#
# Indicates the SAML response issuer
#cas.samlCore.issuer=sso.lib.uts.edu.au
#
# Indicates the skew allowance which controls the issue instant of the SAML response
#cas.samlCore.skewAllowance=60
#
# Indicates whether SAML ticket id generation should be saml2-compliant.
#cas.samlCore.ticketidSaml2=false

##
# CORS handling
#
...

##
# Memcached
#
...

# Monitoring
cas.monitor.memcached.daemon=false

##
# Service ticket behaviour
#
cas.ticket.st.timeToKillInSeconds=60

##
# Service registry
cas.serviceRegistry.json.location=file:/etc/cas/services

# -- / -- #

背景:

我们的组织计划分阶段淘汰 Okta 的 CAS。第一阶段是使用 Okta 作为 CAS 的 IdP,替换定制的 Azure AD/MSAL 模块。鉴于我们的 CAS 即将退役,我们并不热衷于升级到 CAS 6。该组织的 CAS 专家已经离开,并且交给了我,因为我是一名 Java 程序员,而 CAS 是用 Java 编写的。所以至少我可以调试它。毫无疑问,我不是 CAS 专家,而且我发现该手册含糊不清、不完整且缺乏具体示例。

4

0 回答 0