CAS (5) —— Nginx代理模式下浏览器访问CAS服务器配置详解

CAS (5) —— Nginx代理模式下浏览器访问CAS服务器配置详解


tomcat版本: tomcat-8.0.29

jdk版本: jdk1.8.0_65

nginx版本: nginx-1.9.8

cas版本: cas4.1.2
cas-client-3.4.1

参考来源:

jasig.github.io:CAS protocol

https://github.com/Jasig/java-cas-client

通过Proxy访问其它Cas应用

CAS负载均衡配置——SSL篇

CAS负载均衡配置

CAS客户端集群

  • 以下的示例采用我博客的另外两篇文章中搭建好的测试环境举例

CAS (1) —— Mac下配置CAS到Tomcat(服务端)

CAS (2) —— Mac下配置CAS到Tomcat(客户端)

CAS (3) —— Mac下配置CAS客户端经代理访问Tomcat CAS

Mac为nginx安装nginx-sticky-module

【高可用HA】Nginx (1) —— Mac下配置Nginx Http负载均衡(Load Balancer)之101实例

Nginx (2) —— Mac下配置Apache Httpd的Https/SSL (待出)

目标架构

CAS (5) —— Nginx代理模式下浏览器访问CAS服务器配置详解_第1张图片

此代理非彼代理

在CAS官方网站上给出了一个“Proxy Web Flow Diagram”:

CAS (5) —— Nginx代理模式下浏览器访问CAS服务器配置详解_第2张图片

CAS (5) —— Nginx代理模式下浏览器访问CAS服务器配置详解_第3张图片

顺序图:(来源于http://jasig.github.io/cas/4.0.x/protocol/CAS-Protocol.html)

这个方案主要适用一种场景:

有两个应用App1和App2,它们都是受Cas Server保护的,即请求它们时都需要通过Cas Server的认证。现需要在App1中通过Http请求访问App2,显然该请求将会被App2配置的Cas的AuthenticationFilter拦截并转向Cas Server,Cas Server将引导用户进行登录认证,这样我们也就不能真正的访问到App2了。针对这种应用场景,Cas也提供了对应的支持。通过Proxy访问其它Cas应用

无论是用中文关键字在“度娘”,还是用英文关键字再“谷哥”上搜索,多数文章都是描述上面这样一个场景。

而我这里介绍的“代理”,并非是上述场景——依靠代理去验证ticket,“代理”在此的角色是:

  • 只做分发反向代理(未来的负载均衡器)
* 注意:所以说“此代理非彼代理”

准备

要搭建上面这个环境会相对复杂,我们需要参照之前的文章准备以下必备的组件或环境:

  1. 2个Tomcat服务器作为客户端应用程序服务器(即cas的客户端)

     app1.hoau.com:8081/8413(http/https)
     app2.hoau.com:8082/8423(http/https)

    参照Tomcat Cluster、Tomcat SSL和CAS Client

  2. 1个配置好SSL的Nginx服务器作为中间层代理转发服务器(后可扩展为LoadBalancer)

     proxy.sso.hoau.com:85/443(http/https)

    参照Nginx Load Balancer与Nginx Sticky Session

  3. 另一个1个带有SSL的Tomcat服务器作为CAS服务器

     sso.hoau.com:8083/8433(http/https)

    参照Tomcat SSL与CAS Server

关键配置

  • 代理服务器(Nginx x 1)

    nginx.conf
    • http

      server:

        server {
            listen       85;
            server_name  proxy.sso.hoau.com;
            location / {  
            #index index.html index.htm;
            #设置主机头和客户端真实地址,以便服务器获取客户端真实IP
      
            proxy_set_header   Host   $host;
            proxy_set_header   Referer $http_referer;
            proxy_set_header   Cookie $http_cookie;
            proxy_set_header   X-Real-IP  $remote_addr;
            proxy_set_header   X-Forwarded-For              $proxy_add_x_forwarded_for;
      
            proxy_redirect off;  
            #禁用缓存
            #proxy_buffering off;
      
            proxy_connect_timeout 3;
            proxy_send_timeout 30;
            proxy_read_timeout 30; 
            proxy_pass http://cas_server_http; 
        }  

      upstream:

        upstream cas_server_http {  
            #根据ip计算将请求分配各那个后端tomcat,许多人误认为可以解决session问题,其实并不能。  
            #同一机器在多网情况下,路由切换,ip可能不同  
            #ip_hash;   
            #sticky;
      
            #Richard: http
            server localhost:8083 weight=1 srun_id=c; 
            #server localhost:8084 weight=1 srun_id=c; 
            jvm_route $cookie_JSESSIONID|sessionid reverse;
        }

      *注意:

      (1)以上的“jvm_route $cookie_JSESSIONID|sessionid reverse;”是关键配置,因为CAS是依赖于Session和Cookie进行身份验证的。

      (2)srun_id=c,其中“c”需要与CAS服务器Tomcat server.xml文件里的jvmRoute配置“

        
    • https

      server:

        server { 
            listen 443;
            server_name  proxy.sso.hoau.com;
            ssl on; 
            ssl_certificate /Users/Richard/Documents/Dev/servers/cluster/nginx/keys/server.crt; 
            ssl_certificate_key  /Users/Richard/Documents/Dev/servers/cluster/nginx/keys/server.key; 
      
            ssl_session_timeout 5m;
            ssl_protocols SSLv3 TLSv1;
            ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
            ssl_prefer_server_ciphers on;
      
            location / {
                proxy_redirect off;  
      
                proxy_set_header Host $host;  
                proxy_set_header   Referer $http_referer;
                proxy_set_header   Cookie $http_cookie;
                proxy_set_header X-Real-IP $remote_addr;  
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-FORWARDED-HOST $server_addr;  
                proxy_set_header X-FORWARDED-PORT $server_port;
      
                proxy_connect_timeout 3;
                proxy_send_timeout 30;
                proxy_read_timeout 30;
      
                proxy_pass https://cas_server_ssl;
            }   
        }

      *注意:以上的ssl为关键配置“ssl_certificate”和“ssl_certificate_key”需要指向正确的证书和密钥。

      upstream:

        upstream cas_server_ssl {  
            #Richard: https todo
            server sso.hoau.com:8433 weight=1 srun_id=c;  
            #server sso.hoau.com:8443 weight=1 srun_id=c; 
            jvm_route $cookie_JSESSIONID|sessionid reverse;
        }  

*注意:以上http和https可以只配一项,或两者兼存皆可,端口不要冲突。

  • CAS客户端应用服务器(Tomcat x 2)

    以下客户端的蓝本可以在github上收到(关键字:“cas-sample-java-webapp”),我这里只贴出自己的关键点和修改后的结果。

    CAS客户端的应用服务器有两台,如果不使用Spring Security的集成,比较关键配置就只有pom.xml(编译)和web.xml(部署):

    • 两个环境编译类似,pom.xml(贴全了,有无冗余请自行解决):

      *注意:以下Spring Security相关依赖为非必须

        
            4.0.0
            iamlabs.unicon.net
            cas-sample-java-webapp
            0.0.1-SNAPSHOT
            war
            CAS Example Java Web App
            A sample web application that exercises the CAS protocol features via the Java CAS Client.
            
                cas-sample-java-webapp
                
                    
                        org.apache.maven.plugins
                        maven-compiler-plugin
                        2.5.1
                        
                            1.7
                            1.7
                        
                    
                
            
      
                   
                3.2.4.RELEASE 
                3.4.1        
              
      
            
      
            
                commons-logging
                commons-logging
                1.1.1
            
      
                
              
                org.slf4j  
                slf4j-api  
                1.7.13  
              
              
                org.slf4j  
                slf4j-simple  
                1.7.13  
                
                
                org.slf4j    
                slf4j-log4j12    
                1.7.13   
             
      
            
                org.opensaml
                opensaml1
                1.1
            
      
            
                javax.servlet
                javax.servlet-api
                3.1.0
                provided
            
      
            
                org.jasig.cas.client
                cas-client-core
                ${casclient.version}
                
                    
                        javax.servlet
                        servlet-api
                    
                
            
      
            
                org.jasig.cas.client
                cas-client-integration-tomcat-common
                ${casclient.version}
            
      
            
                commons-codec
                commons-codec
                1.6
            
      
            
                org.apache.santuario
                xmlsec
                1.4.3
            
      
              
                org.springframework  
                spring-core  
                ${spring.version}  
              
              
                org.springframework  
                spring-beans  
                ${spring.version}  
             
               
                org.springframework  
                spring-context  
                ${spring.version}  
             
               
                org.springframework  
                spring-web  
                ${spring.version}  
              
      
              
               org.springframework.security
                spring-security-core
                ${spring.version}  
            
              
              org.springframework.security
                spring-security-web
                ${spring.version}  
              
              
                org.springframework.security
                spring-security-config  
                ${spring.version}  
              
            
        
    • https://app1.hoau.com:8413

      web.xml:

        
        
      
      
             
                log4jConfigLocation
                /WEB-INF/log4j.properties
            
      
      
            
                org.springframework.web.util.Log4jConfigListener
            
      
            
      
            
                CAS Validation Filter
                org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
      
                 
                 
      
            
                casServerUrlPrefix
                
                https://proxy.sso.hoau.com:443/cas
            
      
            
      
            
                serverName
                https://app1.hoau.com:8413
            
      
            
                redirectAfterValidation
                true
            
            
                useSession
                true
            
            
                acceptAnyProxy
                true
            
            
            
        
      
        
            CAS Authentication Filter
            org.jasig.cas.client.authentication.AuthenticationFilter
            
            
            
                casServerLoginUrl
                 
                https://proxy.sso.hoau.com:443/cas/login
            
            
                serverName
                https://app1.hoau.com:8413
            
        
      
        
            CAS HttpServletRequest Wrapper Filter
            org.jasig.cas.client.util.HttpServletRequestWrapperFilter
        
      
        
            CAS Validation Filter
            /*
        
      
        
            CAS Authentication Filter
            /*
        
      
        
            CAS HttpServletRequest Wrapper Filter
            /*
        
      
        
        
            
                index.jsp
            
        
        

      *注意:

      • “CAS Validation Filter”需要放在“CAS Authentication Filter”之前
      • 此代理非彼代理

        网上一些文章说的需要配置诸如:
        1. “SingleSignOutHttpSessionListener”
        2. “SingleSignOutFilter”
        3. “ticketValidatorClass”
        4. “ProxyValidate”
        5. “ProxyTicketReceptor”

      均不需要

      • 如果误配了SingleSignOutFilter,会出现异常

        Caused by: java.io.IOException: Server returned HTTP response code: 500 for URL: https://proxy.sso.hoau.com:443/cas/proxyValidate?ticket=ST-31-TM9EbFoQbasNdXh11HaJ-cas01.sso.hoau.com&service=https%3A%2F%2Fapp2.hoau.com%3A8423%2Fcas2%3Bjsessionid%3D0CEB865B53E64FF31BF02A496DF73860.tomcat2
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1840)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
        at org.jasig.cas.client.util.CommonUtils.getResponseFromServer(CommonUtils.java:429)
        ... 24 more

      如果为了在https下录制自动化测试脚本,会修改classpath下/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/security的java.security文件,那么也可能出现类似的错误。

    • https://app2.hoau.com:8423

      web.xml配置同上

      *注意:修改端口

  • CAS服务器(Tomcat x 1)

    • 服务端https://sso.hoau.com:8433

      *注意:

      系列文章CAS (1) —— Mac下配置CAS到Tomcat(服务端)中介绍服务端配置也无需任何修改。

      以下配置:

      1. “Proxy (PGT acquisition)”
      2. “Modern proxy-service validation”

      均不需要

测试

*1. 访问“https://app1.hoau.com:8413/cas1”

CAS (5) —— Nginx代理模式下浏览器访问CAS服务器配置详解_第4张图片

会重定向到“https://proxy.sso.hoau.com/cas/login?service=https%3A%2F%2Fapp1.hoau.com%3A8413%2Fcas1”

*2. 然后输入用户明密码(test01/psw01)

如果验证成功,则会将浏览器重定向到app1的登陆成功页面。

CAS (5) —— Nginx代理模式下浏览器访问CAS服务器配置详解_第5张图片

*3. 再次访问“https://app1.hoau.com:8413/cas1”

可以直接进入登陆成功页,而无需输入用户名密码。

*4. 访问另一应用

同样可以通过test01用户直接进入登陆成功页,而无需输入用户名密码。

CAS (5) —— Nginx代理模式下浏览器访问CAS服务器配置详解_第6张图片

代理下的网络顺序分析

参照另一文章:(待出)

源代码

还在准备,如果需要的童鞋请留言。

结束

你可能感兴趣的:(CAS (5) —— Nginx代理模式下浏览器访问CAS服务器配置详解)