CAS HTTP 401 - 身份验证失败:凭据错误

Posted

技术标签:

【中文标题】CAS HTTP 401 - 身份验证失败:凭据错误【英文标题】:CAS HTTP 401 - Authentication Failed: Bad credentials 【发布时间】:2013-09-22 13:58:38 【问题描述】:

当我尝试登录时,Cas 出现错误,我已经自签名证书并且已经将这些添加到我的密钥库和密钥库到 cacerts,我正在使用 tomcat6 和 maven 生成 .war,我已阅读其他修改代码的解决方案,但这些都不适用于我拥有的代码 谢谢你的帮助

这是来自 CAS 的日志

ServiceValidateController [ERROR] TicketException generating ticket for: [callbackUrl: https://localhost:8443/receptor]
org.jasig.cas.ticket.TicketCreationException: error.authentication.credentials.bad
    at org.jasig.cas.CentralAuthenticationServiceImpl.delegateTicketGrantingTicket(CentralAuthenticationServiceImpl.java:291)
    at org.jasig.cas.web.ServiceValidateController.handleRequestInternal(ServiceValidateController.java:126)
    at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.jasig.cas.web.init.SafeDispatcherServlet.service(SafeDispatcherServlet.java:115)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.inspektr.common.web.ClientInfoThreadLocalFilter.doFilterInternal(ClientInfoThreadLocalFilter.java:48)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:722)
Caused by: error.authentication.credentials.bad
    at org.jasig.cas.authentication.handler.BadCredentialsAuthenticationException.<clinit>(BadCredentialsAuthenticationException.java:25)
    at org.jasig.cas.authentication.AuthenticationManagerImpl.authenticate(AuthenticationManagerImpl.java:113)
    at org.jasig.cas.CentralAuthenticationServiceImpl.delegateTicketGrantingTicket(CentralAuthenticationServiceImpl.java:262)
    ... 26 more

这是来自 Ldap 的日志

geobolivia slapd[3024]: conn=1003 op=3 SRCH base="ou=users,dc=geobolivia,dc=gob,dc=bo" scope=2 deref=3 filter="(uid=geobolivia)"
geobolivia slapd[3024]: conn=1003 op=3 SEARCH RESULT tag=101 err=0 nentries=0 text=
geobolivia slapd[3024]: conn=1003 op=4 SRCH base="ou=users,dc=geobolivia,dc=gob,dc=bo" scope=2 deref=3 filter="(uid=_cas_stateful_)"
geobolivia slapd[3024]: conn=1003 op=4 SEARCH RESULT tag=101 err=0 nentries=0 text=

这些是来自 Security-proxy 的日志

ProxyGrantingTicketStorageImpl [INFO] No Proxy Ticket found for 
FilterBasedLdapUserSearch [DEBUG] Searching for user 'geobolivia', with user search [ searchFilter: '(uid=0)', searchBase: 'ou=users', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
AbstractContextSource [DEBUG] Got Ldap context on server 'ldap://localhost:389/dc=geobolivia,dc=gob,dc=bo'
SpringSecurityLdapTemplate [DEBUG] Searching for entry in under DN 'dc=geobolivia,dc=gob,dc=bo', base = 'ou=users', filter = '(uid=0)'
ProviderManager [DEBUG] Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider
LdapAuthenticationProvider [DEBUG] Processing authentication request for user: _cas_stateful_
FilterBasedLdapUserSearch [DEBUG] Searching for user '_cas_stateful_', with user search [ searchFilter: '(uid=0)', searchBase: 'ou=users', scope: subtree, searchTimeLimit: 0, derefLinkFlag: false ]
AbstractContextSource [DEBUG] Got Ldap context on server 'ldap://localhost:389/dc=geobolivia,dc=gob,dc=bo'
SpringSecurityLdapTemplate [DEBUG] Searching for entry in under DN 'dc=geobolivia,dc=gob,dc=bo', base = 'ou=users', filter = '(uid=0)'
2013-08-29 18:29:15 CasAuthenticationFilter [DEBUG] Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
2013-08-29 18:29:15 CasAuthenticationFilter [DEBUG] Updated SecurityContextHolder to contain null Authentication
CasAuthenticationFilter [DEBUG] Delegating to authentication failure handlerorg.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@1e6ba8ee
SimpleUrlAuthenticationFailureHandler [DEBUG] No failure URL set, sending 401 Unauthorized error
HttpSessionSecurityContextRepository [DEBUG] SecurityContext is empty or anonymous - context will not be stored in HttpSession. 
SecurityContextPersistenceFilter [DEBUG] SecurityContextHolder now cleared, as request processing completed

applicationContext-security.xml的代码就是这些

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:s="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">

    <bean id="properties-loader"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
        p:locations="/WEB-INF/security-proxy.properties" />

    <s:http entry-point-ref="casProcessingFilterEntryPoint" path-type="regex">
        <s:intercept-url pattern=".*\?.*login.*" access="ROLE_SV_USER,ROLE_SV_EDITOR,ROLE_SV_REVIEWER,ROLE_SV_ADMIN" />
        <s:intercept-url pattern="/gssec/.*" access="ROLE_GS_ADMIN" />
        <s:intercept-url pattern="/extractorapp/admin/.*" access="ROLE_ADMINISTRATOR,ROLE_SV_ADMIN" />
        <s:intercept-url pattern="/analytics/.*" access="ROLE_ADMINISTRATOR,ROLE_SV_ADMIN,ROLE_STAT_USER" />
        <s:intercept-url pattern="/test/.*" access="ROLE_GS_ADMIN" />
        <s:intercept-url pattern="/testPage" access="IS_AUTHENTICATED_FULLY" />
<!--        <sec:intercept-url pattern=".*\?.*login.*" access="IS_AUTHENTICATED_FULLY" />-->
        <s:intercept-url pattern=".*" access="IS_AUTHENTICATED_ANONYMOUSLY,ROLE_SV_USER,ROLE_SV_EDITOR,ROLE_SV_REVIEWER,ROLE_SV_ADMIN" />
        <!-- s:form-login / -->
        <s:custom-filter ref="casFilter" after="CAS_FILTER" />
        <s:http-basic/>
        <s:anonymous granted-authority="ROLE_ANONYMOUS"/>
        <s:logout logout-success-url="$logout-success-url"/>
        <!-- Limits the number of concurrent sessions a user can have -->
        <!--<sec:concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true"/>-->

    </s:http>

    <s:authentication-manager alias="authenticationManager">
        <s:authentication-provider ref='casAuthenticationProvider' />
        <s:authentication-provider ref='ldapAuthenticationProvider' />
    </s:authentication-manager>


    <!-- This bean points at the embedded directory server created by the ldap-server element above  -->
    <bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
        <constructor-arg value="$ldapUrl/$baseDN"/>
        <property name="userDn" value="$ldapAdminDn" />
        <property name="password" value="$ldap.admin.password" />
        <property name="baseEnvironmentProperties">
            <map>
                <entry>
                    <key>
                        <value>java.naming.security.authentication</value>
                  </key>
                    <value>simple</value>
                  </entry>
             </map>
         </property>
     </bean>

    <bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
        <constructor-arg index="0" value="$userSearchBaseDN"/>
        <constructor-arg index="1" value="$userSearchFilter"/>
        <constructor-arg index="2" ref="contextSource" />
    </bean>

    <bean id="ldapAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
        <constructor-arg ref="contextSource" />
        <constructor-arg value="$authoritiesBaseDN" />
        <property name="groupSearchFilter" value="$groupSearchFilter"/>
        <property name="rolePrefix" value="ROLE_"/>
        <property name="searchSubtree" value="true"/>
        <property name="convertToUpperCase" value="true"/>
    </bean>

    <bean id="ldapAuthenticationProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
        <constructor-arg>
            <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
                <constructor-arg ref="contextSource" />
                <property name="userSearch" ref="ldapUserSearch"/>
            </bean>
        </constructor-arg>
        <constructor-arg ref="ldapAuthoritiesPopulator" />
    </bean>

    <bean id="userService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
        <constructor-arg index="0" ref="ldapUserSearch" />
        <constructor-arg index="1" ref="ldapAuthoritiesPopulator" />
    </bean>

    <!-- start cas config -->
    <bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">

        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="authenticationFailureHandler">
            <bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
                <property name="defaultFailureUrl" value="/casfailed.jsp"/>
            </bean>
        </property>
        <property name="authenticationSuccessHandler">
            <bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
                <property name="defaultTargetUrl" value="/"/>
            </bean>
        </property>

<!--        <property name="useRelativeContext" value="true" />-->
        <property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />
        <property name="proxyReceptorUrl" value="/receptor" />
    </bean>

    <bean id="casFilter"
      class="org.springframework.security.cas.web.CasAuthenticationFilter">
      <property name="authenticationManager" ref="authenticationManager" />
    </bean>

    <bean id="casProcessingFilterEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
        <property name="loginUrl" value="$casLoginUrl"/>
        <property name="serviceProperties" ref="serviceProperties"/>
    </bean>

    <bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
        <property name="userDetailsService" ref="userService" />
        <property name="serviceProperties" ref="serviceProperties" />
        <property name="ticketValidator">
        <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
                        <constructor-arg index="0" value="$casTicketValidation" />
                        <property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />
                        <property name="proxyCallbackUrl" value="$casCallbackUrl" />
            </bean>
    </property>
        <property name="key" value="security-proxy"/>
    </bean>

    <bean id="proxyGrantingTicketStorage" class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl">
      <constructor-arg index="0" value="7200000" />
    </bean>

    <bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
        <property name="service" value="$proxyCallback"/>
        <property name="sendRenew" value="false"/>
    </bean>

    <!-- end cas config -->
</beans>

接下来是来自 security-proxy.properties 的代码

# ------   proxy-servlet.xml   ---------
proxy.defaultTarget=http://localhost:8080

public.host=geobolivia.gob.bo

# -------  applicationContext-security.xml   -------
anonymousRole=ROLE_ANONYMOUS
proxy.contextPath=/sec
# url called when user has logged out
logout-success-url=https://geobolivia.gob.bo:443/cas/logout?fromgeorchestra
# url where the user can login
casLoginUrl=https://geobolivia.gob.bo:443/cas/login
#url that the security system uses to validate the cas tickets
casTicketValidation=https://localhost:8443/cas
# URL for cas to verify the incoming request
casCallbackUrl=https://localhost:8443/receptor
# After going to the cas login cas forwards to this URL where the authorities and permissions are checked
proxyCallback=https://geobolivia.gob.bo:443/j_spring_cas_security_check
# the ldap url
ldapUrl=ldap://localhost:389
baseDN=dc=geobolivia,dc=gob,dc=bo
# The base DN from where to search for the logged in user.  This mostly to verify the user exists
userSearchBaseDN=ou=users
# the second part of looking up the user
userSearchFilter=(uid=0)
# The base DN to use for looking up the roles/groups/authorities of the logged in user.  Normally the ldap is configured like:
#   ou=groups
#       ou=somegroup
#           member=username
# 
#   ou can be cn, ou, or some other option.  member is often uniquemember as well.  If you don't know what this means you need to
#   research LDAP
authoritiesBaseDN=ou=groups
# The attribute of the group which is the rolename
groupRoleAttribute=cn
# the search filter that selects the groups that the user is part of. 
# If a match is found the containing object is one of the groups the user is part of
groupSearchFilter=(memberUid=uid=1,ou=users,dc=geobolivia,dc=gob,dc=bo)
# the admin user's DN (distinguished name) 
#    Depending on how the LDAP is configured you may be able to comment this and password out and add
#       <property name="anonymousReadOnly" value="true" />
#    to the "ldapContextSource" bean
ldapAdminDn=cn=admin,dc=geobolivia,dc=gob,dc=bo
# The password for binding to the admin user in the ldap
ldap.admin.password=geobolivia

# health check properties
#checkHealth=false
checkHealth=true
psql.host=$shared.psql.host
psql.port=$shared.psql.port
psql.db=$shared.psql.geonetwork.db
psql.user=$shared.psql.user
psql.pass=$shared.psql.pass
psql.url=$shared.psql.url
max.database.connections=170

【问题讨论】:

【参考方案1】:

这可能类似于这个问题:CAS credentials bad。

您可能无意中使用了代理授予票证功能。

【讨论】:

寻求帮助,我通过将用户重新添加到 phpladapadmin 页面中的组解决了这个问题

以上是关于CAS HTTP 401 - 身份验证失败:凭据错误的主要内容,如果未能解决你的问题,请参考以下文章

JMeter NTLM身份验证失败

IIS 7.5 中的 Windows 身份验证失败

不使用 HTTP 基本身份验证时 HTTP 401 未经授权?

HTTP 状态 401 - 身份验证失败:解码传入 SAML 消息时出错

即使凭据为真,Spring Boot Security 也会在 API 调用上引发 401 身份验证错误

WebSocket 连接到 'ws://localhost:8081/.../.../...' 失败:HTTP 身份验证失败;没有可用的有效凭据