1. CAS server: By build a WAR overlay project which contains spnego configurations. And deployed the cas.war on apache-tomcat-9.0.37. cas runs on OS: Linux(Red Hat 7.5) (kerberos installed and configured).
2. kdc(AD domain controller): windows server 2012.
3. client: windows 10 Professional, joined the AD domain.
4. nginx reverse proxy: nginx/1.16.1 (runs on Red Hat 7.5)
First, without nginx, when I accessed cas server directly, I can see the login success page directly without entering username or password. Or when I accessed an application which had been remoulded to a cas client(as well a kdc client) , I can access it directly without login. That is I realized the spnego feature.
But, considering hign availability, I need to deploy a cas cluster. Before cluster deployment, I conducted a test with one nginx server and one cas server, to test if some problems will appear when HTTP requests were fowarded by nginx. Then, problems appeared. Spnego didn't work, I got the login page. The architecture is like this:
client->nginx->cas server->kdc, nginx is a single node, cas server is also a single node, kdc is also a single node.
By combining the nginx log and the cas log, it looks like cas get a wrong spnego token which is decoded from the authorization header. But I have no idea that why cas get a wrong token.
2020-10-15 12:11:01,538 DEBUG [org.springframework.webflow.engine.ActionState] - <Entering state 'startSpnegoAuthenticate' of flow 'login'>
2020-10-15 12:11:01,538 DEBUG [org.springframework.webflow.execution.ActionExecutor] - <Executing [EvaluateAction@52a9f67a expression = negociateSpnego, resultExpression = [null]]>
2020-10-15 12:11:01,538 DEBUG [org.springframework.webflow.execution.ActionExecutor] - <Executing org.apereo.cas.web.flow.SpnegoNegociateCredentialsAction@1eab5ae5>
2020-10-15 12:11:01,538 DEBUG [org.apereo.cas.web.flow.SpnegoNegociateCredentialsAction] - <Authorization header [Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAKAO5CAAAADw==], User Agent header [Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36]>
2020-10-15 12:11:01,539 DEBUG [org.springframework.webflow.execution.ActionExecutor] - <Finished executing org.apereo.cas.web.flow.SpnegoNegociateCredentialsAction@1eab5ae5; result = success>
2020-10-15 12:11:01,539 DEBUG [org.springframework.webflow.execution.ActionExecutor] - <Finished executing [EvaluateAction@52a9f67a expression = negociateSpnego, resultExpression = [null]]; result = success>
2020-10-15 12:11:01,539 DEBUG [org.springframework.webflow.engine.Transition] - <Executing [Transition@20916eb1 on = success, to = spnego]>
2020-10-15 12:11:01,539 DEBUG [org.springframework.webflow.engine.Transition] - <Exiting state 'startSpnegoAuthenticate'>
2020-10-15 12:11:01,539 DEBUG [org.springframework.webflow.engine.ActionState] - <Entering state 'spnego' of flow 'login'>
2020-10-15 12:11:01,539 DEBUG [org.springframework.webflow.execution.ActionExecutor] - <Executing [EvaluateAction@643b792 expression = spnego, resultExpression = [null]]>
2020-10-15 12:11:01,539 DEBUG [org.springframework.webflow.execution.ActionExecutor] - <Executing org.apereo.cas.web.flow.SpnegoCredentialsAction@288b9d98>
2020-10-15 12:11:01,540 DEBUG [org.apereo.cas.web.flow.SpnegoCredentialsAction] - <SPNEGO Authorization header located as [Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAKAO5CAAAADw==]>
2020-10-15 12:11:01,541 DEBUG [org.apereo.cas.web.flow.SpnegoCredentialsAction] - <SPNEGO Authorization header found with [56] bytes>
2020-10-15 12:11:01,543 DEBUG [org.apereo.cas.web.flow.SpnegoCredentialsAction] - <Obtained token: [NTLMSSP ?? B ?].Creating SPNEGO credential...>
2020/10/15 12:13:53 [debug] 22689#0: *103 http process request header line
2020/10/15 12:13:53 [debug] 22689#0: *103 http header: "Host:
nginx.test.com:9991"
2020/10/15 12:13:53 [debug] 22689#0: *103 http header: "Connection: keep-alive"
2020/10/15 12:13:53 [debug] 22689#0: *103 http header: "Authorization: Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAKAO5CAAAADw=="
2020/10/15 12:13:53 [debug] 22689#0: *103 http header: "Upgrade-Insecure-Requests: 1"
2020/10/15 12:13:53 [debug] 22689#0: *103 http header: "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36"
2020/10/15 12:13:53 [debug] 22689#0: *103 http header: "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
2020/10/15 12:13:53 [debug] 22689#0: *103 http header: "Purpose: prefetch"
2020/10/15 12:13:53 [debug] 22689#0: *103 http header: "Accept-Encoding: gzip, deflate"
2020/10/15 12:13:53 [debug] 22689#0: *103 http header: "Accept-Language: zh-CN,zh;q=0.9"
2020/10/15 12:13:53 [debug] 22689#0: *103 http header done
2020/10/15 12:13:53 [debug] 22689#0: *103 generic phase: 0
2020/10/15 12:13:53 [debug] 22689#0: *103 rewrite phase: 1
2020/10/15 12:13:53 [debug] 22689#0: *103 test location: "/"
2020/10/15 12:13:53 [debug] 22689#0: *103 using configuration "/"
2020/10/15 12:13:53 [debug] 22689#0: *103 http cl:-1 max:1048576000
2020/10/15 12:13:53 [debug] 22689#0: *103 rewrite phase: 3
2020/10/15 12:13:53 [debug] 22689#0: *103 post rewrite phase: 4
2020/10/15 12:13:53 [debug] 22689#0: *103 generic phase: 5
2020/10/15 12:13:53 [debug] 22689#0: *103 generic phase: 6
2020/10/15 12:13:53 [debug] 22689#0: *103 generic phase: 7
2020/10/15 12:13:53 [debug] 22689#0: *103 access phase: 8
2020/10/15 12:13:53 [debug] 22689#0: *103 access phase: 9
2020/10/15 12:13:53 [debug] 22689#0: *103 access phase: 10
2020/10/15 12:13:53 [debug] 22689#0: *103 post access phase: 11
2020/10/15 12:13:53 [debug] 22689#0: *103 generic phase: 12
2020/10/15 12:13:53 [debug] 22689#0: *103 generic phase: 13
2020/10/15 12:13:53 [debug] 22689#0: *103 http init upstream, client timer: 0
2020/10/15 12:13:53 [debug] 22689#0: *103 http script copy: "X-Forwarded-For"
2020/10/15 12:13:53 [debug] 22689#0: *103 http script var: "172.28.28.178"
2020/10/15 12:13:53 [debug] 22689#0: *103 http script copy: "X-Real-IP"
2020/10/15 12:13:53 [debug] 22689#0: *103 http script var: "172.28.28.178"
2020/10/15 12:13:53 [debug] 22689#0: *103 http script copy: "Host"
2020/10/15 12:13:53 [debug] 22689#0: *103 http script var: "
nginx.test.com:9991"
2020/10/15 12:13:53 [debug] 22689#0: *103 http script copy: "Connection"
2020/10/15 12:13:53 [debug] 22689#0: *103 http script copy: "close"
2020/10/15 12:13:53 [debug] 22689#0: *103 http script copy: ""
2020/10/15 12:13:53 [debug] 22689#0: *103 http script copy: ""
2020/10/15 12:13:53 [debug] 22689#0: *103 http proxy header: "Authorization: Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAKAO5CAAAADw=="
2020/10/15 12:13:53 [debug] 22689#0: *103 http proxy header: "Upgrade-Insecure-Requests: 1"
2020/10/15 12:13:53 [debug] 22689#0: *103 http proxy header: "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36"
2020/10/15 12:13:53 [debug] 22689#0: *103 http proxy header: "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
2020/10/15 12:13:53 [debug] 22689#0: *103 http proxy header: "Purpose: prefetch"
2020/10/15 12:13:53 [debug] 22689#0: *103 http proxy header: "Accept-Encoding: gzip, deflate"
2020/10/15 12:13:53 [debug] 22689#0: *103 http proxy header: "Accept-Language: zh-CN,zh;q=0.9"
2020/10/15 12:13:53 [debug] 22689#0: *103 http proxy header:
"GET /cas/login HTTP/1.0
X-Forwarded-For: 172.28.28.178
X-Real-IP: 172.28.28.178
Host:
nginx.test.com:9991Connection: close
Authorization: Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAKAO5CAAAADw==
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Purpose: prefetch
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
"
2020/10/15 12:13:53 [debug] 22689#0: *103 http cleanup add: 00000000008B1F78
2020/10/15 12:13:53 [debug] 22689#0: *103 get rr peer, try: 1
2020/10/15 12:13:53 [debug] 22689#0: *103 stream socket 14
2020/10/15 12:13:53 [debug] 22689#0: *103 epoll add connection: fd:14 ev:80002005
2020/10/15 12:13:53 [debug] 22689#0: *103 connect to
172.28.5.146:8080, fd:14 #109
2020/10/15 12:13:53 [debug] 22689#0: *103 http upstream connect: -2
2020/10/15 12:13:53 [debug] 22689#0: *103 posix_memalign: 00000000008680C0:128 @16
2020/10/15 12:13:53 [debug] 22689#0: *103 event timer add: 14: 60000:
45027092122020/10/15 12:13:53 [debug] 22689#0: *103 http finalize request: -4, "/cas/login?" a:1, c:2
2020/10/15 12:13:53 [debug] 22689#0: *103 http request count:2 blk:0
2020/10/15 12:13:53 [debug] 22689#0: *103 http run request: "/cas/login?"
2020/10/15 12:13:53 [debug] 22689#0: *103 http upstream check client, write event:1, "/cas/login"
2020/10/15 12:13:53 [debug] 22689#0: timer delta: 98
2020/10/15 12:13:53 [debug] 22689#0: worker cycle
2020/10/15 12:13:53 [debug] 22689#0: epoll timer: 60000
2020/10/15 12:13:53 [debug] 22689#0: epoll: fd:14 ev:0004 d:00007FA77C2E8790
2020/10/15 12:13:53 [debug] 22689#0: *103 http upstream request: "/cas/login?"
2020/10/15 12:13:53 [debug] 22689#0: *103 http upstream send request handler
2020/10/15 12:13:53 [debug] 22689#0: *103 http upstream send request
2020/10/15 12:13:53 [debug] 22689#0: *103 http upstream send request body
2020/10/15 12:13:53 [debug] 22689#0: *103 chain writer buf fl:1 s:597
2020/10/15 12:13:53 [debug] 22689#0: *103 chain writer in: 00000000008B1FB8
2020/10/15 12:13:53 [debug] 22689#0: *103 writev: 597 of 597
2020/10/15 12:13:53 [debug] 22689#0: *103 chain writer out: 0000000000000000
2020/10/15 12:13:53 [debug] 22689#0: *103 event timer del: 14:
45027092122020/10/15 12:13:53 [debug] 22689#0: *103 event timer add: 14: 3600000:
4506249215The client obtained a service ticket from kdc already, and the client sended the spnego token(i.e. the http authorization header) to nginx. Nginx forwarded the request to cas server. So, Nginx forwaded the request that carried the spnego token already, the authorization header was also forwarded. The cas server also received the request which contains the spnego token already.
But the spnego token that is obtained from kdc is wrong.
The correct spnego token is like this(When a client access cas server directly,without nginx, the spnego token the cas server obtained is correct ):