CAS Spnego - KrbException:校验和失败
CAS Spnego - KrbException: Checksum failed
我正在尝试将 SPNEGO (Kerberos) 身份验证与 Active Directory - 与 CAS 服务器 (github) 结合使用。
这是官方说明:https://apereo.github.io/cas/5.1.x/installation/SPNEGO-Authentication.html
我使用了这个模板:https://github.com/apereo/cas-overlay-template
所以 pom.xml
是从那里拿来的。
不幸的是,我只收到这个异常:
>>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
jcifs.spnego.AuthenticationException: Error performing Kerberos authentication: java.lang.reflect.InvocationTargetException
at jcifs.spnego.Authentication.processKerberos(Authentication.java:447)
at jcifs.spnego.Authentication.processSpnego(Authentication.java:346)
at jcifs.spnego.Authentication.process(Authentication.java:235)
at jcifs.spnego.Authentication$$FastClassBySpringCGLIB$$c5958df9.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at jcifs.spnego.Authentication$$EnhancerBySpringCGLIB$bb5e21.process(<generated>)
at org.apereo.cas.support.spnego.authentication.handler.support.JcifsSpnegoAuthenticationHandler.doAuthentication(JcifsSpnegoAuthenticationHandler.java:60)
at org.apereo.cas.authentication.handler.support.AbstractPreAndPostProcessingAuthenticationHandler.authenticate(AbstractPreAndPostProcessingAuthenticationHandler.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy118.authenticate(Unknown Source)
at org.apereo.cas.authentication.AbstractAuthenticationManager.authenticateAndResolvePrincipal(AbstractAuthenticationManager.java:174)
at org.apereo.cas.authentication.PolicyBasedAuthenticationManager.lambda$null(PolicyBasedAuthenticationManager.java:129)
at java.util.stream.MatchOpsMatchSink.accept(Unknown Source)
at java.util.stream.ReferencePipeline.accept(Unknown Source)
at java.util.Spliterators$IteratorSpliterator.tryAdvance(Unknown Source)
at java.util.stream.ReferencePipeline.forEachWithCancel(Unknown Source)
at java.util.stream.AbstractPipeline.copyIntoWithCancel(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.util.stream.MatchOps$MatchOp.evaluateSequential(Unknown Source)
at java.util.stream.MatchOps$MatchOp.evaluateSequential(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.util.stream.ReferencePipeline.anyMatch(Unknown Source)
at org.apereo.cas.authentication.PolicyBasedAuthenticationManager.lambda$authenticateInternal(PolicyBasedAuthenticationManager.java:126)
at java.util.stream.MatchOpsMatchSink.accept(Unknown Source)
at java.util.HashMap$KeySpliterator.tryAdvance(Unknown Source)
at java.util.stream.ReferencePipeline.forEachWithCancel(Unknown Source)
at java.util.stream.AbstractPipeline.copyIntoWithCancel(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.util.stream.MatchOps$MatchOp.evaluateSequential(Unknown Source)
at java.util.stream.MatchOps$MatchOp.evaluateSequential(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.util.stream.ReferencePipeline.anyMatch(Unknown Source)
at org.apereo.cas.authentication.PolicyBasedAuthenticationManager.authenticateInternal(PolicyBasedAuthenticationManager.java:124)
at org.apereo.cas.authentication.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:140)
at org.apereo.cas.authentication.AbstractAuthenticationManager$$FastClassBySpringCGLIB$a86894.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
at org.apereo.inspektr.audit.AuditTrailManagementAspect.handleAuditTrail(AuditTrailManagementAspect.java:134)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.ryantenney.metrics.spring.MeteredMethodInterceptor.invoke(MeteredMethodInterceptor.java:45)
at com.ryantenney.metrics.spring.MeteredMethodInterceptor.invoke(MeteredMethodInterceptor.java:32)
at com.ryantenney.metrics.spring.AbstractMetricMethodInterceptor.invoke(AbstractMetricMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.ryantenney.metrics.spring.TimedMethodInterceptor.invoke(TimedMethodInterceptor.java:48)
at com.ryantenney.metrics.spring.TimedMethodInterceptor.invoke(TimedMethodInterceptor.java:34)
at com.ryantenney.metrics.spring.AbstractMetricMethodInterceptor.invoke(AbstractMetricMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.ryantenney.metrics.spring.CountedMethodInterceptor.invoke(CountedMethodInterceptor.java:46)
at com.ryantenney.metrics.spring.CountedMethodInterceptor.invoke(CountedMethodInterceptor.java:32)
at com.ryantenney.metrics.spring.AbstractMetricMethodInterceptor.invoke(AbstractMetricMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.ryantenney.metrics.spring.MeteredMethodInterceptor.invoke(MeteredMethodInterceptor.java:45)
at com.ryantenney.metrics.spring.MeteredMethodInterceptor.invoke(MeteredMethodInterceptor.java:32)
at com.ryantenney.metrics.spring.AbstractMetricMethodInterceptor.invoke(AbstractMetricMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.ryantenney.metrics.spring.TimedMethodInterceptor.invoke(TimedMethodInterceptor.java:48)
at com.ryantenney.metrics.spring.TimedMethodInterceptor.invoke(TimedMethodInterceptor.java:34)
at com.ryantenney.metrics.spring.AbstractMetricMethodInterceptor.invoke(AbstractMetricMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.ryantenney.metrics.spring.CountedMethodInterceptor.invoke(CountedMethodInterceptor.java:46)
at com.ryantenney.metrics.spring.CountedMethodInterceptor.invoke(CountedMethodInterceptor.java:32)
at com.ryantenney.metrics.spring.AbstractMetricMethodInterceptor.invoke(AbstractMetricMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at org.apereo.cas.authentication.PolicyBasedAuthenticationManager$$EnhancerBySpringCGLIB$85e4b0.authenticate(<generated>)
at org.apereo.cas.authentication.DefaultAuthenticationTransactionManager.handle(DefaultAuthenticationTransactionManager.java:34)
at org.apereo.cas.authentication.DefaultAuthenticationSystemSupport.handleAuthenticationTransaction(DefaultAuthenticationSystemSupport.java:55)
at org.apereo.cas.authentication.DefaultAuthenticationSystemSupport.handleInitialAuthenticationTransaction(DefaultAuthenticationSystemSupport.java:41)
at org.apereo.cas.web.flow.resolver.impl.InitialAuthenticationAttemptWebflowEventResolver.resolveInternal(InitialAuthenticationAttemptWebflowEventResolver.java:69)
at org.apereo.cas.web.flow.resolver.impl.AbstractCasWebflowEventResolver.resolve(AbstractCasWebflowEventResolver.java:475)
at org.apereo.cas.web.flow.resolver.impl.AbstractCasWebflowEventResolver.resolveSingle(AbstractCasWebflowEventResolver.java:480)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy164.resolveSingle(Unknown Source)
at org.apereo.cas.web.flow.AbstractAuthenticationAction.doExecute(AbstractAuthenticationAction.java:59)
at org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:188)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy160.execute(Unknown Source)
at org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:51)
at org.springframework.webflow.action.EvaluateAction.doExecute(EvaluateAction.java:77)
at org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:188)
at org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:51)
at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:101)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Transition.execute(Transition.java:228)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
at org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:105)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Transition.execute(Transition.java:228)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
at org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:105)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Transition.execute(Transition.java:228)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
at org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:105)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Transition.execute(Transition.java:228)
at org.springframework.webflow.engine.DecisionState.doEnter(DecisionState.java:51)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Transition.execute(Transition.java:228)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
at org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:105)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Transition.execute(Transition.java:228)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
at org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:105)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Flow.start(Flow.java:527)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:368)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:223)
at org.springframework.webflow.executor.FlowExecutorImpl.launchExecution(FlowExecutorImpl.java:140)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy158.launchExecution(Unknown Source)
at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:263)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apereo.cas.web.support.AuthenticationCredentialsLocalBinderClearingFilter.doFilter(AuthenticationCredentialsLocalBinderClearingFilter.java:28)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apereo.cas.security.RequestParameterPolicyEnforcementFilter.doFilter(RequestParameterPolicyEnforcementFilter.java:261)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apereo.cas.security.ResponseHeadersEnforcementFilter.doFilter(ResponseHeadersEnforcementFilter.java:238)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apereo.cas.logging.web.ThreadContextMDCServletFilter.doFilter(ThreadContextMDCServletFilter.java:90)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:115)
at org.springframework.boot.web.support.ErrorPageFilter.access[=10=]0(ErrorPageFilter.java:59)
at org.springframework.boot.web.support.ErrorPageFilter.doFilterInternal(ErrorPageFilter.java:90)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apereo.inspektr.common.web.ClientInfoThreadLocalFilter.doFilter(ClientInfoThreadLocalFilter.java:64)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at jcifs.spnego.Authentication$ServerAction.run(Authentication.java:517)
at jcifs.spnego.Authentication.processKerberos(Authentication.java:430)
... 274 more
Caused by: GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)
at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
... 280 more
Caused by: KrbException: Checksum failed
at sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Unknown Source)
at sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Unknown Source)
at sun.security.krb5.EncryptedData.decrypt(Unknown Source)
at sun.security.krb5.KrbApReq.authenticate(Unknown Source)
at sun.security.krb5.KrbApReq.<init>(Unknown Source)
at sun.security.jgss.krb5.InitSecContextToken.<init>(Unknown Source)
... 283 more
Caused by: java.security.GeneralSecurityException: Checksum failed
at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decryptCTS(Unknown Source)
at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decrypt(Unknown Source)
at sun.security.krb5.internal.crypto.Aes256.decrypt(Unknown Source)
... 289 more
问题:
这是什么意思?哪个配置元素可能导致此问题?
我找到了解决方案。简而言之:我在 cas.properties
.
中有不好的 cas.authn.spnego.jcifsServicePrincipal
详情:
- 活动目录
- JDK 1.8 + JCE
- Apereo CAS 5.1
- Tomcat Windows 服务器 2012 R2 上的 8.5.15
CAS documentation 建议这样的配置:
cas.authn.spnego.jcifsServicePrincipal=HTTP/cas.example.com@EXAMPLE.COM
但请注意,jcifsServicePrincipal
是 principal 名称 - Active Directory user 的名称,它具有 SPN分配。
我有用户 cn=service_xxx
,其 servicePrincipalName
属性分配给 HTTP/machine1.domain.com
和 HTTP/machine1
(但我认为,只需要第一个)。
值得学习本教程:Kerberos / SPNEGO based SSO (Single Sign-On) in Weblogic。
我的 CAS 是如何工作的:
使用上面的教程,我为现有用户 service_xxx 创建了 SPN(可以登录 machine1 的用户):
setspn -s HTTP/machine1.domain.com service_xxx
用户 service_xxx 在 Active Directory 中具有这样的属性:AES 128 位加密和 AES 256 位加密。
这两个操作都是由 Active Directory 管理员完成的(他有足够的权限)。
所以service_xxx
是主体名称(用户名),HTTP/machine1.domain.com
只是分配给主体的SPN属性。据我了解 - 现在机器 machine1.domain.com
上的 CAS 服务器 运行(这是机器 URL)可以从用户 service_xxx
的 AD (LDAP) 中获取任何信息。因此 CAS 服务器也可以使用 Kerberos 协议对任何用户进行身份验证。在我看来,这就是为什么 CAS 属性 jcifsServicePrincipal
应该指向主体 service_xxx@domain.com
(带@domain.com 的完整主体名称)而不是它的 SPN 属性名称(除非他们是相等的字符串)。
我的配置详情:
- 具有 AES 属性和 SPN 属性集的主体
- Java 安装了 Java 加密扩展 (JCE) 无限强度
- 使用来自 JDK 的
ktab.exe
工具创建的密钥表
login.conf
文件 - 与 CAS documentation 中的相同
cas.properties
和krb5.conf
如下图
密钥表
密钥选项卡创建过程(不需要任何特殊权限):
"C:\Program Files\Java\jre1.8.0_131\bin\ktab.exe" -a service_xxx -n 0 -k cas.keytab
-k
指定密钥选项卡输出文件名。 -n 0
指定 KNVO 编号。免责声明:我的用户 cn=service_xxx 在 Active Directory 中没有属性 msDS-KeyVersionNumber
(KNVO),所以我使用了 0。但我认为 Windows 忽略了 KNVO 编号 - 请参阅 this comment.
有关 keytab 的更多信息:
很多教程甚至官方 documentation 建议使用 ktpass.exe
制作密钥表。不幸的是,这需要 AD 管理员权限,所以这不是一个好主意。最好使用 JDK 中的 ktab.exe
(如上所述)。您只需要记住总是在 service_xxx
更改密码后生成新的密钥表。
要测试按键选项卡,有几个选项:
- 使用 kinit 收集 kerberos 票据(对于 service_xxx 主体)。这也是 JDK.
提供的工具
- 试试这个由来自 SO 的@Ivan Veselovsky 编写的小应用程序:
cas.properties
对我有用:
cas.authn.spnego.kerberosConf=/etc/cas/config/krb5.conf
cas.authn.spnego.jcifsServicePrincipal=service_xxx@domain.com
cas.authn.spnego.loginConf=file:/etc/cas/config/login.conf
cas.authn.spnego.kerberosRealm=DOMAIN.COM
cas.authn.spnego.principal.principalAttribute=sAMAccountName
cas.authn.spnego.ldap.ldapUrl=ldap://path.to.ldap.domain.com
cas.authn.spnego.ldap.baseDn=DC=domain,DC=com #this is base dn where LDAP starts searching for users
cas.authn.spnego.ldap.bindDn=cn=SERVICE_XXX,DC=domain,DC=com #it's a kind of login to LDAP
cas.authn.spnego.ldap.failFast=false
cas.authn.spnego.ldap.subtreeSearch=true
cas.authn.spnego.ldap.useSsl=false
cas.authn.spnego.ldap.searchFilter=cn={host}
有趣的是,像 /etc/cas/config
这样的路径也适用于 Windows 并指向 C:
驱动器根目录 - 所以 C:\etc\cas\config
。请注意,此处的所有配置(以及所有 Java 文件)路径都使用正斜杠。
我也供应krb5.conf。此文件特定于您的组织。通常,您可以在连接到域的任何工作站的 C:\Windows
文件夹中的某处找到它。所以你可以复制它,并根据需要进行编辑。您也可以手写(示例在 CAS 文档中)。
最重要的是添加密钥表的路径:
[libdefaults]
default_keytab_name = C:/Users/SERVICE_XXX/my_keytab/cas.keytab
如您所见 - default_keytab_name
参数在 [libdefaults]
下。 login.conf
文件中也有相同的路径(请参阅 Apereo CAS 文档)。
如果您在 CAS 中启用调试(cas.authn.spnego.kerberosDebug=true
并在 log4j2.xml
中更改调试级别)。然后您应该看到 CAS 何时使用您的密钥表,例如:
2017-07-04 19:56:29,613 DEBUG [org.apereo.cas.support.spnego.authentication.handler.support.JcifsSpnegoAuthenticationHandler] - <Processing SPNEGO authentication>
Java config name: /etc/cas/config/krb5.conf
Loaded from Java config
Found KeyTab Default keytab
Entered Krb5Context.acceptSecContext with state=STATE_NEW
>>> KeyTabInputStream, readName(): DOMAIN.COM
>>> KeyTabInputStream, readName(): SERVICE_XXX
>>> KeyTab: load() entry length: 79; type: 18
// ... edited
Added key: 23version: 0
Added key: 16version: 0
Added key: 17version: 0
Added key: 18version: 0
否则,你会看到 CAS Looking for keys for: service_xxx@domain.com
然后抛出类似于下面的异常。
疑难解答 1:
如果您看到与此类似的异常:
Caused by: GSSException: Failure unspecified at GSS-API level (Mechanism level: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - AES256 CTS mode with HMAC SHA1-96)
at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
... 280 more
Caused by: KrbException: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - AES256 CTS mode with HMAC SHA1-96
at sun.security.krb5.KrbApReq.authenticate(Unknown Source)
at sun.security.krb5.KrbApReq.<init>(Unknown Source)
at sun.security.jgss.krb5.InitSecContextToken.<init>(Unknown Source)
... 283 more
很有可能,您 .keytab
文件的路径有误(也如 所指)。
疑难解答 2:
如果 CAS 抱怨不支持加密:
Encryption type AES256 CTS mode with HMAC SHA1-96 is not supported/enabled
可能 Java JCE 未安装或 Java 已更新,结果 JCE 支持被更新覆盖(再次安装 JCE)。
在我的例子中,我必须在 CATALINA_OPTS
中设置 属性 javax.security.auth.useSubjectCredsOnly=true
CAS(版本5.2.x)使用jcifs.spnego,这个使用这个属性(Authentication class,反编译第414行,不好意思没找到源代码)以便使用(或不使用)服务帐户凭据进行连接。
我正在尝试将 SPNEGO (Kerberos) 身份验证与 Active Directory - 与 CAS 服务器 (github) 结合使用。 这是官方说明:https://apereo.github.io/cas/5.1.x/installation/SPNEGO-Authentication.html
我使用了这个模板:https://github.com/apereo/cas-overlay-template
所以 pom.xml
是从那里拿来的。
不幸的是,我只收到这个异常:
>>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
jcifs.spnego.AuthenticationException: Error performing Kerberos authentication: java.lang.reflect.InvocationTargetException
at jcifs.spnego.Authentication.processKerberos(Authentication.java:447)
at jcifs.spnego.Authentication.processSpnego(Authentication.java:346)
at jcifs.spnego.Authentication.process(Authentication.java:235)
at jcifs.spnego.Authentication$$FastClassBySpringCGLIB$$c5958df9.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at jcifs.spnego.Authentication$$EnhancerBySpringCGLIB$bb5e21.process(<generated>)
at org.apereo.cas.support.spnego.authentication.handler.support.JcifsSpnegoAuthenticationHandler.doAuthentication(JcifsSpnegoAuthenticationHandler.java:60)
at org.apereo.cas.authentication.handler.support.AbstractPreAndPostProcessingAuthenticationHandler.authenticate(AbstractPreAndPostProcessingAuthenticationHandler.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy118.authenticate(Unknown Source)
at org.apereo.cas.authentication.AbstractAuthenticationManager.authenticateAndResolvePrincipal(AbstractAuthenticationManager.java:174)
at org.apereo.cas.authentication.PolicyBasedAuthenticationManager.lambda$null(PolicyBasedAuthenticationManager.java:129)
at java.util.stream.MatchOpsMatchSink.accept(Unknown Source)
at java.util.stream.ReferencePipeline.accept(Unknown Source)
at java.util.Spliterators$IteratorSpliterator.tryAdvance(Unknown Source)
at java.util.stream.ReferencePipeline.forEachWithCancel(Unknown Source)
at java.util.stream.AbstractPipeline.copyIntoWithCancel(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.util.stream.MatchOps$MatchOp.evaluateSequential(Unknown Source)
at java.util.stream.MatchOps$MatchOp.evaluateSequential(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.util.stream.ReferencePipeline.anyMatch(Unknown Source)
at org.apereo.cas.authentication.PolicyBasedAuthenticationManager.lambda$authenticateInternal(PolicyBasedAuthenticationManager.java:126)
at java.util.stream.MatchOpsMatchSink.accept(Unknown Source)
at java.util.HashMap$KeySpliterator.tryAdvance(Unknown Source)
at java.util.stream.ReferencePipeline.forEachWithCancel(Unknown Source)
at java.util.stream.AbstractPipeline.copyIntoWithCancel(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.util.stream.MatchOps$MatchOp.evaluateSequential(Unknown Source)
at java.util.stream.MatchOps$MatchOp.evaluateSequential(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.util.stream.ReferencePipeline.anyMatch(Unknown Source)
at org.apereo.cas.authentication.PolicyBasedAuthenticationManager.authenticateInternal(PolicyBasedAuthenticationManager.java:124)
at org.apereo.cas.authentication.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:140)
at org.apereo.cas.authentication.AbstractAuthenticationManager$$FastClassBySpringCGLIB$a86894.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
at org.apereo.inspektr.audit.AuditTrailManagementAspect.handleAuditTrail(AuditTrailManagementAspect.java:134)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.ryantenney.metrics.spring.MeteredMethodInterceptor.invoke(MeteredMethodInterceptor.java:45)
at com.ryantenney.metrics.spring.MeteredMethodInterceptor.invoke(MeteredMethodInterceptor.java:32)
at com.ryantenney.metrics.spring.AbstractMetricMethodInterceptor.invoke(AbstractMetricMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.ryantenney.metrics.spring.TimedMethodInterceptor.invoke(TimedMethodInterceptor.java:48)
at com.ryantenney.metrics.spring.TimedMethodInterceptor.invoke(TimedMethodInterceptor.java:34)
at com.ryantenney.metrics.spring.AbstractMetricMethodInterceptor.invoke(AbstractMetricMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.ryantenney.metrics.spring.CountedMethodInterceptor.invoke(CountedMethodInterceptor.java:46)
at com.ryantenney.metrics.spring.CountedMethodInterceptor.invoke(CountedMethodInterceptor.java:32)
at com.ryantenney.metrics.spring.AbstractMetricMethodInterceptor.invoke(AbstractMetricMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.ryantenney.metrics.spring.MeteredMethodInterceptor.invoke(MeteredMethodInterceptor.java:45)
at com.ryantenney.metrics.spring.MeteredMethodInterceptor.invoke(MeteredMethodInterceptor.java:32)
at com.ryantenney.metrics.spring.AbstractMetricMethodInterceptor.invoke(AbstractMetricMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.ryantenney.metrics.spring.TimedMethodInterceptor.invoke(TimedMethodInterceptor.java:48)
at com.ryantenney.metrics.spring.TimedMethodInterceptor.invoke(TimedMethodInterceptor.java:34)
at com.ryantenney.metrics.spring.AbstractMetricMethodInterceptor.invoke(AbstractMetricMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at com.ryantenney.metrics.spring.CountedMethodInterceptor.invoke(CountedMethodInterceptor.java:46)
at com.ryantenney.metrics.spring.CountedMethodInterceptor.invoke(CountedMethodInterceptor.java:32)
at com.ryantenney.metrics.spring.AbstractMetricMethodInterceptor.invoke(AbstractMetricMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at org.apereo.cas.authentication.PolicyBasedAuthenticationManager$$EnhancerBySpringCGLIB$85e4b0.authenticate(<generated>)
at org.apereo.cas.authentication.DefaultAuthenticationTransactionManager.handle(DefaultAuthenticationTransactionManager.java:34)
at org.apereo.cas.authentication.DefaultAuthenticationSystemSupport.handleAuthenticationTransaction(DefaultAuthenticationSystemSupport.java:55)
at org.apereo.cas.authentication.DefaultAuthenticationSystemSupport.handleInitialAuthenticationTransaction(DefaultAuthenticationSystemSupport.java:41)
at org.apereo.cas.web.flow.resolver.impl.InitialAuthenticationAttemptWebflowEventResolver.resolveInternal(InitialAuthenticationAttemptWebflowEventResolver.java:69)
at org.apereo.cas.web.flow.resolver.impl.AbstractCasWebflowEventResolver.resolve(AbstractCasWebflowEventResolver.java:475)
at org.apereo.cas.web.flow.resolver.impl.AbstractCasWebflowEventResolver.resolveSingle(AbstractCasWebflowEventResolver.java:480)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy164.resolveSingle(Unknown Source)
at org.apereo.cas.web.flow.AbstractAuthenticationAction.doExecute(AbstractAuthenticationAction.java:59)
at org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:188)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy160.execute(Unknown Source)
at org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:51)
at org.springframework.webflow.action.EvaluateAction.doExecute(EvaluateAction.java:77)
at org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:188)
at org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:51)
at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:101)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Transition.execute(Transition.java:228)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
at org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:105)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Transition.execute(Transition.java:228)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
at org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:105)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Transition.execute(Transition.java:228)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
at org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:105)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Transition.execute(Transition.java:228)
at org.springframework.webflow.engine.DecisionState.doEnter(DecisionState.java:51)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Transition.execute(Transition.java:228)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
at org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:105)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Transition.execute(Transition.java:228)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.execute(FlowExecutionImpl.java:395)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214)
at org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java:116)
at org.springframework.webflow.engine.Flow.handleEvent(Flow.java:547)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent(FlowExecutionImpl.java:390)
at org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent(RequestControlContextImpl.java:210)
at org.springframework.webflow.engine.ActionState.doEnter(ActionState.java:105)
at org.springframework.webflow.engine.State.enter(State.java:194)
at org.springframework.webflow.engine.Flow.start(Flow.java:527)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:368)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.start(FlowExecutionImpl.java:223)
at org.springframework.webflow.executor.FlowExecutorImpl.launchExecution(FlowExecutorImpl.java:140)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy158.launchExecution(Unknown Source)
at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:263)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apereo.cas.web.support.AuthenticationCredentialsLocalBinderClearingFilter.doFilter(AuthenticationCredentialsLocalBinderClearingFilter.java:28)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apereo.cas.security.RequestParameterPolicyEnforcementFilter.doFilter(RequestParameterPolicyEnforcementFilter.java:261)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apereo.cas.security.ResponseHeadersEnforcementFilter.doFilter(ResponseHeadersEnforcementFilter.java:238)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apereo.cas.logging.web.ThreadContextMDCServletFilter.doFilter(ThreadContextMDCServletFilter.java:90)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:115)
at org.springframework.boot.web.support.ErrorPageFilter.access[=10=]0(ErrorPageFilter.java:59)
at org.springframework.boot.web.support.ErrorPageFilter.doFilterInternal(ErrorPageFilter.java:90)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apereo.inspektr.common.web.ClientInfoThreadLocalFilter.doFilter(ClientInfoThreadLocalFilter.java:64)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at jcifs.spnego.Authentication$ServerAction.run(Authentication.java:517)
at jcifs.spnego.Authentication.processKerberos(Authentication.java:430)
... 274 more
Caused by: GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)
at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
... 280 more
Caused by: KrbException: Checksum failed
at sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Unknown Source)
at sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Unknown Source)
at sun.security.krb5.EncryptedData.decrypt(Unknown Source)
at sun.security.krb5.KrbApReq.authenticate(Unknown Source)
at sun.security.krb5.KrbApReq.<init>(Unknown Source)
at sun.security.jgss.krb5.InitSecContextToken.<init>(Unknown Source)
... 283 more
Caused by: java.security.GeneralSecurityException: Checksum failed
at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decryptCTS(Unknown Source)
at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decrypt(Unknown Source)
at sun.security.krb5.internal.crypto.Aes256.decrypt(Unknown Source)
... 289 more
问题: 这是什么意思?哪个配置元素可能导致此问题?
我找到了解决方案。简而言之:我在 cas.properties
.
cas.authn.spnego.jcifsServicePrincipal
详情:
- 活动目录
- JDK 1.8 + JCE
- Apereo CAS 5.1
- Tomcat Windows 服务器 2012 R2 上的 8.5.15
CAS documentation 建议这样的配置:
cas.authn.spnego.jcifsServicePrincipal=HTTP/cas.example.com@EXAMPLE.COM
但请注意,jcifsServicePrincipal
是 principal 名称 - Active Directory user 的名称,它具有 SPN分配。
我有用户 cn=service_xxx
,其 servicePrincipalName
属性分配给 HTTP/machine1.domain.com
和 HTTP/machine1
(但我认为,只需要第一个)。
值得学习本教程:Kerberos / SPNEGO based SSO (Single Sign-On) in Weblogic。
我的 CAS 是如何工作的:
使用上面的教程,我为现有用户 service_xxx 创建了 SPN(可以登录 machine1 的用户):
setspn -s HTTP/machine1.domain.com service_xxx
用户 service_xxx 在 Active Directory 中具有这样的属性:AES 128 位加密和 AES 256 位加密。
这两个操作都是由 Active Directory 管理员完成的(他有足够的权限)。
所以service_xxx
是主体名称(用户名),HTTP/machine1.domain.com
只是分配给主体的SPN属性。据我了解 - 现在机器 machine1.domain.com
上的 CAS 服务器 运行(这是机器 URL)可以从用户 service_xxx
的 AD (LDAP) 中获取任何信息。因此 CAS 服务器也可以使用 Kerberos 协议对任何用户进行身份验证。在我看来,这就是为什么 CAS 属性 jcifsServicePrincipal
应该指向主体 service_xxx@domain.com
(带@domain.com 的完整主体名称)而不是它的 SPN 属性名称(除非他们是相等的字符串)。
我的配置详情:
- 具有 AES 属性和 SPN 属性集的主体
- Java 安装了 Java 加密扩展 (JCE) 无限强度
- 使用来自 JDK 的
ktab.exe
工具创建的密钥表 login.conf
文件 - 与 CAS documentation 中的相同
cas.properties
和krb5.conf
如下图
密钥表
密钥选项卡创建过程(不需要任何特殊权限):
"C:\Program Files\Java\jre1.8.0_131\bin\ktab.exe" -a service_xxx -n 0 -k cas.keytab
-k
指定密钥选项卡输出文件名。 -n 0
指定 KNVO 编号。免责声明:我的用户 cn=service_xxx 在 Active Directory 中没有属性 msDS-KeyVersionNumber
(KNVO),所以我使用了 0。但我认为 Windows 忽略了 KNVO 编号 - 请参阅 this comment.
有关 keytab 的更多信息:
很多教程甚至官方 documentation 建议使用 ktpass.exe
制作密钥表。不幸的是,这需要 AD 管理员权限,所以这不是一个好主意。最好使用 JDK 中的 ktab.exe
(如上所述)。您只需要记住总是在 service_xxx
更改密码后生成新的密钥表。
要测试按键选项卡,有几个选项:
- 使用 kinit 收集 kerberos 票据(对于 service_xxx 主体)。这也是 JDK. 提供的工具
- 试试这个由来自 SO 的@Ivan Veselovsky 编写的小应用程序:
cas.properties
对我有用:
cas.authn.spnego.kerberosConf=/etc/cas/config/krb5.conf
cas.authn.spnego.jcifsServicePrincipal=service_xxx@domain.com
cas.authn.spnego.loginConf=file:/etc/cas/config/login.conf
cas.authn.spnego.kerberosRealm=DOMAIN.COM
cas.authn.spnego.principal.principalAttribute=sAMAccountName
cas.authn.spnego.ldap.ldapUrl=ldap://path.to.ldap.domain.com
cas.authn.spnego.ldap.baseDn=DC=domain,DC=com #this is base dn where LDAP starts searching for users
cas.authn.spnego.ldap.bindDn=cn=SERVICE_XXX,DC=domain,DC=com #it's a kind of login to LDAP
cas.authn.spnego.ldap.failFast=false
cas.authn.spnego.ldap.subtreeSearch=true
cas.authn.spnego.ldap.useSsl=false
cas.authn.spnego.ldap.searchFilter=cn={host}
有趣的是,像 /etc/cas/config
这样的路径也适用于 Windows 并指向 C:
驱动器根目录 - 所以 C:\etc\cas\config
。请注意,此处的所有配置(以及所有 Java 文件)路径都使用正斜杠。
我也供应krb5.conf。此文件特定于您的组织。通常,您可以在连接到域的任何工作站的 C:\Windows
文件夹中的某处找到它。所以你可以复制它,并根据需要进行编辑。您也可以手写(示例在 CAS 文档中)。
最重要的是添加密钥表的路径:
[libdefaults]
default_keytab_name = C:/Users/SERVICE_XXX/my_keytab/cas.keytab
如您所见 - default_keytab_name
参数在 [libdefaults]
下。 login.conf
文件中也有相同的路径(请参阅 Apereo CAS 文档)。
如果您在 CAS 中启用调试(cas.authn.spnego.kerberosDebug=true
并在 log4j2.xml
中更改调试级别)。然后您应该看到 CAS 何时使用您的密钥表,例如:
2017-07-04 19:56:29,613 DEBUG [org.apereo.cas.support.spnego.authentication.handler.support.JcifsSpnegoAuthenticationHandler] - <Processing SPNEGO authentication>
Java config name: /etc/cas/config/krb5.conf
Loaded from Java config
Found KeyTab Default keytab
Entered Krb5Context.acceptSecContext with state=STATE_NEW
>>> KeyTabInputStream, readName(): DOMAIN.COM
>>> KeyTabInputStream, readName(): SERVICE_XXX
>>> KeyTab: load() entry length: 79; type: 18
// ... edited
Added key: 23version: 0
Added key: 16version: 0
Added key: 17version: 0
Added key: 18version: 0
否则,你会看到 CAS Looking for keys for: service_xxx@domain.com
然后抛出类似于下面的异常。
疑难解答 1:
如果您看到与此类似的异常:
Caused by: GSSException: Failure unspecified at GSS-API level (Mechanism level: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - AES256 CTS mode with HMAC SHA1-96)
at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
... 280 more
Caused by: KrbException: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - AES256 CTS mode with HMAC SHA1-96
at sun.security.krb5.KrbApReq.authenticate(Unknown Source)
at sun.security.krb5.KrbApReq.<init>(Unknown Source)
at sun.security.jgss.krb5.InitSecContextToken.<init>(Unknown Source)
... 283 more
很有可能,您 .keytab
文件的路径有误(也如
疑难解答 2:
如果 CAS 抱怨不支持加密:
Encryption type AES256 CTS mode with HMAC SHA1-96 is not supported/enabled
可能 Java JCE 未安装或 Java 已更新,结果 JCE 支持被更新覆盖(再次安装 JCE)。
在我的例子中,我必须在 CATALINA_OPTS
中设置 属性 javax.security.auth.useSubjectCredsOnly=trueCAS(版本5.2.x)使用jcifs.spnego,这个使用这个属性(Authentication class,反编译第414行,不好意思没找到源代码)以便使用(或不使用)服务帐户凭据进行连接。