java - 使用数据库身份验证设置 CAS Jasig 服务器

标签 java authentication single-sign-on cas

我正在尝试通过 CAS 服务器设置单点登录。我想使用数据库身份验证,因为我有使用 spring security 的现有应用程序通过 MySQL 进行身份验证。

我正在按照 official site 上的说明进行操作,使用他们的基础 Maven 覆盖项目作为我的起点。从网站上的说明来看,添加数据库身份验证处理程序似乎很简单 - 定义 bean(数据库处理程序、密码编码器和数据源)并将处理程序添加到authenticationManager bean 上的处理程序列表中。

当我尝试登录/cas/login 时,没有任何反应。没有查询访问数据库,就好像根本不考虑处理程序一样。该网页不会显示有关错误凭据的错误。 tomcat日志没有给出任何错误或任何错误迹象,我不知所措。我还需要设置什么?

我的deployerConfigContext.xml如下。我只编辑/添加了到passwordEncoder 的内容。其他一切都来自 Maven Overlay 项目附带的默认配置。

感谢您的帮助,新年快乐!

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:p="http://www.springframework.org/schema/p"
   xmlns:c="http://www.springframework.org/schema/c"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xmlns:util="http://www.springframework.org/schema/util"
   xmlns:sec="http://www.springframework.org/schema/security"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
   http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
   http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

<!--
   | The authentication manager defines security policy for authentication by specifying at a minimum
   | the authentication handlers that will be used to authenticate credential. While the AuthenticationManager
   | interface supports plugging in another implementation, the default PolicyBasedAuthenticationManager should
   | be sufficient in most cases.
   +-->
<bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager">
    <constructor-arg>
        <list>
        <ref bean="dbAuthHandler" />
     </list>
    </constructor-arg>

    <!-- Uncomment the metadata populator to allow clearpass to capture and cache the password
         This switch effectively will turn on clearpass.
    <property name="authenticationMetaDataPopulators">
       <util:list>
          <bean class="org.jasig.cas.extension.clearpass.CacheCredentialsMetaDataPopulator"
                c:credentialCache-ref="encryptedMap" />
       </util:list>
    </property>
    -->

    <!--
       | Defines the security policy around authentication. Some alternative policies that ship with CAS:
       |
       | * NotPreventedAuthenticationPolicy - all credential must either pass or fail authentication
       | * AllAuthenticationPolicy - all presented credential must be authenticated successfully
       | * RequiredHandlerAuthenticationPolicy - specifies a handler that must authenticate its credential to pass
       -->
    <property name="authenticationPolicy">
        <bean class="org.jasig.cas.authentication.AnyAuthenticationPolicy" />
    </property>
</bean>

<!--
   | TODO: Replace this component with one suitable for your enviroment.
   |
   | This component provides authentication for the kind of credential used in your environment. In most cases
   | credential is a username/password pair that lives in a system of record like an LDAP directory.
   | The most common authentication handler beans:
   |
   | * org.jasig.cas.authentication.LdapAuthenticationHandler
   | * org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler
   | * org.jasig.cas.adaptors.x509.authentication.handler.support.X509CredentialsAuthenticationHandler
   | * org.jasig.cas.support.spnego.authentication.handler.support.JCIFSSpnegoAuthenticationHandler
   -->
<bean id="dbAuthHandler"    class="org.jasig.cas.adaptors.jdbc.SearchModeSearchDatabaseAuthenticationHandler">
  <property name="dataSource" ref="secureDataSource"></property>
  <property name="passwordEncoder" ref="passwordEncoder"></property>
  <property name="tableUsers" value="sec_user"></property>
  <property name="fieldUser" value="username"></property>
  <property name="fieldPassword" value="password"></property>
</bean>

<bean id="secureDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
   <property name="driverClassName" value="${secure.db.driver}"/>
   <property name="url" value="${secure.db.url}"/>
   <property name="username" value="${secure.db.username}"/>
   <property name="password" value="${secure.db.password}"/>
   <property name="maxActive" value="${secure.db.max.active}"/>
   <property name="maxIdle" value="${secure.db.max.idle}"/>
   <property name="minIdle" value="${secure.db.min.idle}"/>
   <property name="testOnBorrow" value="${secure.db.testOnBorrow}"></property>
   <property name="validationQuery" value="select 1"></property>
</bean>

<bean id="passwordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
   <constructor-arg value="SHA256"></constructor-arg>
   <property name="characterEncoding" value="UTF-8"></property>
</bean>

<!-- Required for proxy ticket mechanism -->
<bean id="proxyPrincipalResolver"
      class="org.jasig.cas.authentication.principal.BasicPrincipalResolver" />

<!--
   | Resolves a principal from a credential using an attribute repository that is configured to resolve
   | against a deployer-specific store (e.g. LDAP).
   -->
<bean id="primaryPrincipalResolver"
      class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver" >
    <property name="attributeRepository" ref="attributeRepository" />
</bean>

<!--
Bean that defines the attributes that a service may return.  This example uses the Stub/Mock version.  A real implementation
may go against a database or LDAP server.  The id should remain "attributeRepository" though.
+-->
<bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao"
        p:backingMap-ref="attrRepoBackingMap" />

<util:map id="attrRepoBackingMap">
    <entry key="uid" value="uid" />
    <entry key="eduPersonAffiliation" value="eduPersonAffiliation" /> 
    <entry key="groupMembership" value="groupMembership" />
</util:map>

<!-- 
Sample, in-memory data store for the ServiceRegistry. A real implementation
would probably want to replace this with the JPA-backed ServiceRegistry DAO
The name of this bean should remain "serviceRegistryDao".
+-->
<bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl"
        p:registeredServices-ref="registeredServicesList" />

<util:list id="registeredServicesList">
    <bean class="org.jasig.cas.services.RegexRegisteredService"
          p:id="0" p:name="HTTP and IMAP" p:description="Allows HTTP(S) and IMAP(S) protocols"
          p:serviceId="^(https?|imaps?)://.*" p:evaluationOrder="10000001" />
    <!--
    Use the following definition instead of the above to further restrict access
    to services within your domain (including sub domains).
    Note that example.com must be replaced with the domain you wish to permit.
    This example also demonstrates the configuration of an attribute filter
    that only allows for attributes whose length is 3.
    -->
    <!--
    <bean class="org.jasig.cas.services.RegexRegisteredService">
        <property name="id" value="1" />
        <property name="name" value="HTTP and IMAP on example.com" />
        <property name="description" value="Allows HTTP(S) and IMAP(S) protocols on example.com" />
        <property name="serviceId" value="^(https?|imaps?)://([A-Za-z0-9_-]+\.)*example\.com/.*" />
        <property name="evaluationOrder" value="0" />
        <property name="attributeFilter">
          <bean class="org.jasig.cas.services.support.RegisteredServiceRegexAttributeFilter" c:regex="^\w{3}$" /> 
        </property>
    </bean>
    -->
</util:list>

<bean id="auditTrailManager" class="com.github.inspektr.audit.support.Slf4jLoggingAuditTrailManager" />

<bean id="healthCheckMonitor" class="org.jasig.cas.monitor.HealthCheckMonitor" p:monitors-ref="monitorsList" />

<util:list id="monitorsList">
  <bean class="org.jasig.cas.monitor.MemoryMonitor" p:freeMemoryWarnThreshold="10" />
  <!--
    NOTE
    The following ticket registries support SessionMonitor:
      * DefaultTicketRegistry
      * JpaTicketRegistry
    Remove this monitor if you use an unsupported registry.
  -->
  <bean class="org.jasig.cas.monitor.SessionMonitor"
      p:ticketRegistry-ref="ticketRegistry"
      p:serviceTicketCountWarnThreshold="5000"
      p:sessionCountWarnThreshold="100000" />
</util:list>

更新: 出于调试目的,这里有两个日志文件。一种是您在此处看到的部署配置,另一种是默认配置。

我的:http://pastebin.com/9tRLPDq8

默认:http://pastebin.com/pxrUJMQG

在默认情况下,我故意使用错误的凭据。我看到的最显着的差异就在审核(?)消息之前:

我的:

2015-01-02 09:58:15,515 DEBUG [org.springframework.webflow.execution.ActionExecutor] - <Executing [EvaluateAction@cdb588 expression = authenticationViaFormAction.submit(flowRequestContext, flowScope.credential, messageContext), resultExpression = [null]]>
2015-01-02 09:58:15,515 DEBUG [org.springframework.webflow.execution.AnnotatedAction] - <Putting action execution attributes map[[empty]]>
2015-01-02 09:58:15,515 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Returning cached instance of singleton bean 'authenticationViaFormAction'>
2015-01-02 09:58:15,517 INFO [org.perf4j.TimingLogger] - <start[1420221495517] time[0] tag[AUTHENTICATE]>
2015-01-02 09:58:15,518 INFO [com.github.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: audit:unknown
...

默认:

2015-01-02 10:07:53,246 DEBUG [org.springframework.webflow.execution.AnnotatedAction] - <Putting action execution attributes map[[empty]]>
2015-01-02 10:07:53,246 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Returning cached instance of singleton bean 'authenticationViaFormAction'>
2015-01-02 10:07:53,266 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Returning cached instance of singleton bean 'auditTrailManagementAspect'>
2015-01-02 10:07:53,267 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Returning cached instance of singleton bean 'timingAspect'>
2015-01-02 10:07:53,272 DEBUG [org.jasig.cas.authentication.AcceptUsersAuthenticationHandler] - <admin was not found in the map.>
2015-01-02 10:07:53,272 INFO [org.jasig.cas.authentication.PolicyBasedAuthenticationManager] - <AcceptUsersAuthenticationHandler failed authenticating admin+password>
2015-01-02 10:07:53,272 INFO [org.perf4j.TimingLogger] - <start[1420222073269] time[2] tag[AUTHENTICATE]>
2015-01-02 10:07:53,277 INFO [com.github.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: audit:unknown
...

更新2: 我深入研究了源代码,并将日志消息与预期的消息进行了比较。正在查看the authenticateInternal method ,当使用数据库处理程序时,我没有看到任何日志消息,而当我使用默认处理程序时,我会看到它们。假设我实际上达到了这个方法,唯一可能失败且没有消息的地方似乎是 for (final Credential credential : credentials) {...}

添加系统信息: CAS 4.0.0 Tomcat 7 JDK 1.7 MySQL 5.5.22

更新3: 嗯,它一直就在那里看着我......

WHO: audit:unknown
WHAT: java.security.NoSuchAlgorithmException: SHA256 MessageDigest not available**
ACTION: TICKET_GRANTING_TICKET_NOT_CREATED
APPLICATION: CAS
WHEN: Fri Jan 02 09:58:15 PST 2015
CLIENT IP ADDRESS: 0:0:0:0:0:0:0:1
SERVER IP ADDRESS: 0:0:0:0:0:0:0:1

最佳答案

免责声明:我是 CAS 主席,也是云中 CAS 的创始人 ( https://www.casinthecloud.com )。

奇怪!配置看起来不错。您确定覆盖层已正确构建(覆盖正确目录中的 deployerConfigContext.xml 文件)吗?

您应该已在 cas.log 文件 ( https://github.com/Jasig/cas/blob/4.0.x/cas-server-webapp/src/main/resources/log4j.xml ) 中包含 INFO 日志。看看这些日志...

关于java - 使用数据库身份验证设置 CAS Jasig 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27727522/

相关文章:

java - 在 JAVA 中使用 CAS 服务器进行单点登录

java - 如何实现具有泛型返回类型和泛型参数的泛型方法?

java - 从 java 提交 HTML 表单需要 cookies 和弹出窗口拦截器

java - 在 ubuntu 中使用特定 JRE 运行 .jar

java - 带空格的 Hadoop 目录

single-sign-on - Edge Chromium 不会将 SAML 数据通过 http 发布到 IEMode 用户访问 URL

django - 401 未经授权 ("detail":"Authentication credentials were not provided.")

node.js - Passport 中的用户权限级别

tomcat - 使用独立 Tomcat 的 Spring Boot 容器身份验证

javascript - 如何通过 SSO 将 header 变量传递到我的 Angular 2 应用程序?