设为首页 收藏本站
查看: 671|回复: 0

[经验分享] CAS sso配置

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2016-7-20 10:27:59 | 显示全部楼层 |阅读模式
最近在研究sso单点登录的问题,研究了网上许多案例以及代码,发现总是有很大的差别,最后通过官网下载,才发现cas3 与 cas 4 的配置存在区别,这就是差别很大的原因了。
官网地址如下: https://www.apereo.org/search/node/cas

下面只针对cas4进行整理吧,因为cas4 相对于cas3 来说,是有增无减了。
1.下载
地址http://downloads.jasig.org/
cas-server-4.0.0-release.tar.gz
cas-client-3.3.3-release.tar.gz

2.配置Sever端
解压cas-server-4.0.0,将其中module/cas-server-webapp-4.0.0.war复制到Tomcat的webapps目录下,重命名为cas.war,启动Tomcat解开压缩
启动tomcat

http://localhost:8080/cas,进入登录页面。
默认用户为casuser/Mellon,登录成功即启动正常,cas3的无默认用户,只需用户名密码一直即可。

2.1设置利用数据库来验证用户

需依赖:c3p0-0.9.1.2.jar,mysql-connector-java-5.1.21.jar,cas-server-support-jdbc-4.0.0.jar,cas-server-support-ldap-4.0.0.jar
修改 deployerConfigContext.xml


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1)更换验证方式

   <!--
   <bean id="primaryAuthenticationHandler"
          class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">
        <property name="users">
            <map>
                <entry key="casuser" value="Mellon"/>
            </map>
        </property>
    </bean>
    -->

    <!-- Define the DB Connection -->
    <bean id="dbAuthHandler" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"
      p:dataSource-ref="dataSource"
      p:sql="select passwd from users where name=?" />


     <!-- 使用dataSource-->
     <bean id="dataSource"
     class="com.mchange.v2.c3p0.ComboPooledDataSource"
     p:driverClass="com.mysql.jdbc.Driver"
     p:jdbcUrl="jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&amp;characterEncoding=utf-8"
     p:user="root"
     p:password="123" />



1
2
3
4
5
6
7
8
9
10
2)更换handler验证方式
<bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager">
    <constructor-arg>
        <map>
            <entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
             <entry key-ref="dbAuthHandler" value-ref="primaryPrincipalResolver" />
             <!--本来使用primaryAuthenticationHandler,现在使用dbAuthHandler -->
            <!-- <entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" /> -->
        </map>
    </constructor-arg>



注释了原来的默认用户,使用数据库替代,新建数据库test,暂时没有使用md5加密,数据库test的users表直接设置passwd和name即可
1
2
3
4
5
6
7
8
9
3)使用md5加密,密码校验类自定义实现
<bean id="dbAuthHandler" class="com.test.cas.MyQueryDatabaseAuthenticationHandler"
      p:dataSource-ref="dataSource"
      p:sql="select passwd from users where name=?"
      p:passwordEncoder-ref="passwordEncoder"/>

<bean id="passwordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"
      c:encodingAlgorithm="md5"
      p:characterEncoding="UTF-8" />  



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
4)密码校验类自定义实现

public class MyQueryDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler{
    @NotNull
    private String sql;

    @Override
    protected HandlerResult authenticateUsernamePasswordInternal(UsernamePasswordCredential credential)throws GeneralSecurityException, PreventedException {
         final String username = credential.getUsername();

          final String encryptedPassword = this.getPasswordEncoder().encode(credential.getPassword()+"{"+username+"}");
            try {
                final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username);
                if (!dbPassword.equals(encryptedPassword)) {
                    throw new FailedLoginException("Password does not match value on record.");
                }
            } catch (final IncorrectResultSizeDataAccessException e) {
                if (e.getActualSize() == 0) {
                    throw new AccountNotFoundException(username + " not found with SQL query");
                } else {
                    throw new FailedLoginException("Multiple records found for " + username);
                }
            } catch (final DataAccessException e) {
                throw new PreventedException("SQL exception while executing query for " + username, e);
            }
            return createHandlerResult(credential, new SimplePrincipal(username), null);
    }

    public void setSql(final String sql) {
        this.sql = sql;
    }
}




因为这里的密码采用了   密码{用户名}  加密的方式,所以使用了自定义的密码校验,重启,测试通过

3.配置Client端
3.1 普通方式
新建testweb项目,在Client工程WEB-INF/lib下添加cas-client-core-3.2.1.jar包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
修改web.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>testWeb1</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>

<!-- ======================== 单点登录/登出 ======================== -->

<!-- 定义serverName,一个全局变量 -->
    <context-param>
        <param-name>serverName</param-name>
        <param-value>http://localhost:8080</param-value>
    </context-param>


<!-- 该过滤器用于实现单点登出功能,可选配置。 -->
<filter>
   <filter-name>CAS Single Sign Out Filter</filter-name>
   <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>

<!-- 该过滤器负责用户的认证工作,必须启用它 -->
<filter>
  <filter-name>CAS Authentication Filter</filter-name>
  <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
  <init-param>
    <param-name>casServerLoginUrl</param-name>
    <param-value>https://localhost:8080/cas/login</param-value>
  </init-param>
</filter>

<!-- 该过滤器负责对Ticket的校验工作,必须启用它 -->
<filter>
    <filter-name>CAS Validation Filter</filter-name>
    <filter-class>org.jasig.cas.client.validation.Cas10TicketValidationFilter</filter-class>
    <init-param>
        <param-name>casServerUrlPrefix</param-name>
        <param-value>https://localhost:8080/cas</param-value>
    </init-param>
    <init-param>
        <param-name>redirectAfterValidation</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

<!-- 该过滤器负责实现HttpServletRequest请求的包裹,
比如允许开发者通过HttpServletRequest的getRemoteUser()方法获得SSO登录用户的登录名,可选配置。 -->
<filter>
  <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
  <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>

<!-- 该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。
比如AssertionHolder.getAssertion().getPrincipal().getName()。-->
<filter>
  <filter-name>CAS Assertion Thread Local Filter</filter-name>
  <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>

<!-- 对所有请求进行拦截-->
<filter-mapping>
   <filter-name>CAS Single Sign Out Filter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>CAS Authentication Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>CAS Validation Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>CAS Assertion Thread Local Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
    <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>
<!-- ======================== 单点登录/登出结束 ======================== -->

     <servlet>
        <servlet-name>HelloWorldExample</servlet-name>
        <servlet-class>servlets.HelloWorld</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloWorldExample</servlet-name>
        <url-pattern>HelloWorldExample</url-pattern>
    </servlet-mapping>  

</web-app>




这里配置了HelloWorld servlet 来配合测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class HelloWorld extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException
    {
        AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
        String username = principal.getName();
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Hello World</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>Hello World!"+username+"</h1>");
        out.println("</body>");
        out.println("</html>");
    }
}



访问localhost:8080/testWeb1/HelloWorldExample  ,首次访问任一页面就会跳转到
https://localhost:8080/cas/login进行认证

3.2 spring 方式
这里采用spring security 与cas结合的方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<!-- entry-point-ref入口点的意思,当捕捉到尚未登陆,尝试访问其他url时,会自动跳到入口点 -->
<http  auto-config="true" entry-point-ref="casAuthenticationEntryPoint" >
    <custom-filter ref="myFilter"   before="FILTER_SECURITY_INTERCEPTOR" />

    <!-- CasAuthenticationFilter总是监听/j_spring_cas_security_check请求 -->
    <!-- 认证请求将被配置的AuthenticationManager处理 -->
    <custom-filter position="CAS_FILTER" ref="casAuthenticationFilter" />

    <access-denied-handler ref="accessDeniedHandler"></access-denied-handler>
</http>

<beans:bean id="casAuthenticationEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
    <beans:property name="loginUrl" value="http://sso.test.com/login"></beans:property>
    <!-- service指定了回调url,当认证成功时,会跳回到这 -->
    <beans:property name="serviceProperties" ref="serviceProperties"></beans:property>
</beans:bean>

<!-- service指定了回调url,当认证成功时,会跳回到这 -->
<beans:bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
    <beans:property name="service" value="http://localhost:8080/testweb/j_spring_cas_security_check"></beans:property>
    <beans:property name="sendRenew" value="false"></beans:property>
</beans:bean>

<!--当sso验证成功后,所有请求会在此处理 -->
<beans:bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
    <beans:property name="authenticationUserDetailsService" ref="authenticationUserDetailsService"/>
    <beans:property name="serviceProperties" ref="serviceProperties"></beans:property>
    <!-- 校验服务票据 -->
    <!-- Cas20TicketValidator 解析从CAS服务器收到的XML,它给CasAuthenticationProvider 返回一个TicketResponse,其中包含用户名和代理列表 -->
    <!-- 接下来将请求AuthenticationUserDetailsService 去加载应用于包含在Assertion中用户的GrantedAuthority 对象 -->
    <beans:property name="ticketValidator">
        <beans:bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
        <!-- 配置cas服务器 -->
            <beans:constructor-arg index="0" value="http://sso.test.com/" />
        </beans:bean>
    </beans:property>
    <beans:property name="key" value="cas" />
</beans:bean>

    <!-- authorities对应 CAS server的 登录属性, 在此设置到spirng security中,用于spring security的验证 -->
    <beans:bean id="authenticationUserDetailsService" class="com.test.security.MyGrantedAuthorityFromAssertionAttributesUserDetailsService">
    </beans:bean>

    <authentication-manager alias="authenticationManager">
        <authentication-provider ref="casAuthenticationProvider"></authentication-provider>
    </authentication-manager>

    <!-- cas 认证失败控制器 -->  
    <beans:bean id="authenticationFailureHandler"  class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">  
        <beans:property name="defaultFailureUrl" value="/login?error=error" />
    </beans:bean>  
    <!-- cas 认证成功控制器 -->  
    <beans:bean id="authenticationSuccessHandler"  class="com.test.AuthenticationSuccessHandler">  
        <beans:property name="defaultTargetUrl" value="/" />
    </beans:bean>

    <beans:bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
        <beans:property name="authenticationManager" ref="authenticationManager"></beans:property>
        <beans:property name="authenticationFailureHandler" ref="authenticationFailureHandler" />
        <beans:property name="authenticationSuccessHandler" ref="authenticationSuccessHandler" />
        <beans:property name="filterProcessesUrl" value="/j_spring_cas_security_check" />
    </beans:bean>







运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-246797-1-1.html 上篇帖子: rsync+inotify节点间文件实时同步 下篇帖子: Linux rename命令文件重命名的用法汇总
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表