• cas单点登录系统:客户端(client)详细配置(重要)


    最近一直在研究cas登录中心这一块的应用,分享一下记录的一些笔记和心得。后面会把cas-server端的配置和重构,另外还有这几天再搞nginx+cas的https反向代理配置,以及cas的证书相关的知识分享出来。

    Cas由两部分组成,Cas Server和Cas Client。Cas Server是Cas自己的服务端,而Cas Client是Cas客户端,往往客户端需要和我们具体的业务系统进行集成,这里我们主要详述cas 客户端的配置以及实例

    第一步:

    我们得有一个现成的web项目,然后我们要加入cas-client-core-xxx.jar到classpath;

    maven项目用这个:

    <dependency>
    	<groupId>org.jasig.cas.client</groupId>
    	<artifactId>cas-client-core</artifactId>
    	<version>3.3.3</version>
    </dependency>

    这里我使用 cas-client-core-3.3.3.jar,顺便推荐一个用来搜索和下载引用包的网站,我一般从这里下载引用包:http://mvnrepository.com/artifact/org.jasig.cas.client/cas-client-core/3.3.3

     

    第二步:配置Filter

     我们需要在应用的web.xml文件中配置四个Filter,这四个Filter必须按照固定的顺序来进行配置,而且它们必须配置在应用的其它Filter之前。它们的先后顺序要求如下:
    1、AuthenticationFilter
    2、TicketValidationFilter
    3、HttpServletRequestWrapperFilter
    4、AssertionThreadLocalFilter

    1.1、 配置AuthenticationFilter

     1.1.1、AuthenticationFilter有两个必须指定的参数:

    casServerLoginUrl用来指定Cas Server登录地址,serverName或service用来指定认证成功后需要跳转地址。

    补充:

    service和serverName一般只需要指定一个,如果都指定了,参数service将具有更高的优先级,即以service指定的参数值为准。

    service和serverName的区别:

    service指定的是一个确定的URL,认证成功后就会确切的跳转到service指定的URL;

    serverName用来指定主机名,格式为{http/https}:{主机名}:{端口号}

    如:https://localhost:8335,当指定的是serverName时,AuthenticationFilter将会把它附加上当前请求的URI,以及对应的查询参数来构造一个确定的URL,如指定serverName为“http://localhost”,而当前请求的URI为“/login”,查询参数为“user=123&pwd=123”,则对应认证成功后的跳转地址将为“http://localhost/login?user=123&pwd=123”。)

     AuthenticationFilter可以指定如下可选参数:
    renew:当指定renew为true时,在请Cas Server时将带上参数“renew=true”,默认为false。
    gateway:指定gateway为true时,在请求Cas Server时将带上参数“gateway=true”,默认为false。
    artifactParameterName:指定ticket对应的请求参数名称,默认为ticket。
    serviceParameterName:指定service对应的请求参数名称,默认为service。

    例如,我是这样配置的:

    <filter>
          <filter-name>casAuthenticationFilter</filter-name>
       <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
          <init-param>
             <param-name>casServerLoginUrl</param-name>
             <param-value>https://cas.eguid.cn:8335/cas-server/</param-value>
          </init-param>
          <init-param>
             <param-name>serverName</param-name>
             <param-value>http://sso.eguid.cn:8080/</param-value>
          </init-param>
       </filter>
       <filter-mapping>
          <filter-name>casAuthenticationFilter</filter-name>
          <url-pattern>/*</url-pattern>
       </filter-mapping>



    1.2、配置TicketValidationFilter

    请求通过AuthenticationFilter的认证之后,如果请求中携带了参数ticket则将会由TicketValidationFilter来对携带的ticket进行校验。

    TicketValidationFilter只是对验证ticket的这一类Filter的统称,其并不对应Cas Client中的一个具体类型。

    Cas Client中有多种验证ticket的Filter,都继承自AbstractTicketValidationFilter,它们的验证逻辑都是一致的,都有AbstractTicketValidationFilter实现,不同的是使用的TicketValidator不一样。这里我们使用Cas10TicketValidationFilter,也可以使用Cas20ProxyReceivingTicketValidationFilter或者Saml11TicketValidationFilter。

    <filter>
          <filter-name>casTicketValidationFilter</filter-name>
       <filter-class>org.jasig.cas.client.validation.Cas10TicketValidationFilter</filter-class>
          <init-param>
             <param-name>casServerUrlPrefix</param-name>
             <param-value>https://cas.eguid.cn:8335/cas-server/</param-value>
          </init-param>
            <init-param>
             <param-name>serverName</param-name>
             <param-value>http://sso.eguid.cn:8080/</param-value>
          </init-param>
       </filter>
       <filter-mapping>
          <filter-name>casTicketValidationFilter</filter-name>
          <url-pattern>/*</url-pattern>
       </filter-mapping>


    必须指定的参数:

    casServerUrlPrefix 用来指定Cas Server对应URL地址的前缀,如上面示例的“https://cas.eguid.cn:8335/cas-server。
    serverName或service:与前面的用法相同。

      

    可选参数:
    redirectAfterValidation :表示是否验证通过后重新跳转到该URL,但是不带参数ticket,默认为true。
    useSession :                在验证ticket成功后会生成一个Assertion对象,如果useSession为true,则会将该对象存放到Session中。如果为false,则要求每次请求都需要携带ticket进行验证,显然useSession为false跟redirectAfterValidation为true是冲突的。默认为true。
    exceptionOnValidationFailure :表示ticket验证失败后是否需要抛出异常,默认为true。
    renew:                         当值为true时将发送“renew=true”到Cas Server,默认为false。
     
    1.3、配置HttpServletRequestWrapperFilter

     HttpServletRequestWrapperFilter用于将每一个请求对应的HttpServletRequest封装为其内部定义的CasHttpServletRequestWrapper,该封装类将利用之前保存在Session或request中的Assertion对象重写HttpServletRequest的getUserPrincipal()、getRemoteUser()和isUserInRole()方法。这样在我们的应用中就可以非常方便的从HttpServletRequest中获取到用户的相关信息。

     <filter>
          <filter-name>casHttpServletRequestWrapperFilter</filter-name>
       <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
       </filter>
       <filter-mapping>
          <filter-name>casHttpServletRequestWrapperFilter</filter-name>
          <url-pattern>/*</url-pattern>
       </filter-mapping>


    1.4、配置AssertionThreadLocalFilter

     AssertionThreadLocalFilter可以在应用的其它地方获取Assertion对象,找个过滤器会把Assertion对象存放到当前的线程变量中,我们在程序的任何地方都可以从线程变量中获取当前Assertion,就不需要再从Session或request中进行解析了。这个线程变量是由AssertionHolder持有的,我们在获取当前的Assertion时也只需要通过AssertionHolder的getAssertion()方法获取即可,如:
       Assertion assertion = AssertionHolder.getAssertion();

    我是这样配置的:

    <filter>
          <filter-name>casAssertionThreadLocalFilter</filter-name>
         <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
       </filter>
       <filter-mapping>
          <filter-name>casAssertionThreadLocalFilter</filter-name>
          <url-pattern>/*</url-pattern>
       </filter-mapping>


    cient端到这里就配置完成了,随便写个页面,把这个应用部署到tomcat容器测试一下,尝试打开页面,你会发现跳转进入了cas-server(cas服务端)的登录页面。

    当你真的登录成功后,你会发现,你回不到原来页面了!怎么办?其实我们只要在前端给他一个参数就行了,可以这样简单实现这个功能:

    //登录中心url
    var loginCenter = "https://cas.eguid.cn:8335/cas-server";
    function getUrl() {
    	var hostname = location.href;
    	return hostname;
    }
    //登陆
    function login() {
    	location.href = loginCenter + "/login?service=" + getUrl();
    }
    //登录中心执行登出操作
    function logoutServ()
    {
    	alert("开始登出");
    	var loginUrl = loginCenter + "/login?service=" + getUrl();
    	location.href = loginCenter + "/logout?service=" + loginUrl;
    }

    在页面上的你得有登录和退出两个按钮,分别调用login()和logoutServ()方法。

    其实这里还有个小问题,就是虽然你在cas-server端注销了,你会发现它依然会认为你现在是登录状态,所以没有拦截你的请求。

    这是因为它时基于session验证的,你的server端session已经注销了,但是客户端应用这里的session还没有注销

    一般我们会使用共享session的方法解决这个问题,另外有个简单的方法就是你可以在后台写个用来注销当前用户session的接口。

  • 相关阅读:
    redis为何单线程 效率还这么高 为何使用跳表不使用B+树做索引(阿里)
    阿里笔试-生产者消费者模式
    调用 redis 原子命令,保证多线程安全 的incr命令问题
    忽略警告注解@SuppressWarnings详解
    怎样查出连续数字中缺失的数字
    IDEA-Maven的Dependencies中出现红色波浪线
    Java实现AES加密(window机器和linux机器) 注意window机器 和linux机器算法稍有不同
    PR代码提交规范
    接口的幂等性,如何保证
    bash 括号(小括号,双小括号,中括号,双中括号,大括号)
  • 原文地址:https://www.cnblogs.com/liuys635/p/14320483.html
Copyright © 2020-2023  润新知