单点登录

一、单点登录的概念与功能

单点登录的英文简称为SSO(single sign on),单点登录功能使得用户只要登录了其中一个系统,就可以访问其他相关系统,而不用进行身份验证登录。即用户只要登陆系统一次,该用户的身份信息就可以被系统中的多个主机上的应用所识别,不需要在访问每个应用时再分别进行登陆。

二单点登录的两种解决方案

1.在某个域范围内的全局Cookie,另一个同域名系统可以通过cookie获取用户信息然后进行验证,这样可以实现单点登录。
单点登录_第1张图片
例如:Set-Cookie2: user=it315; Version=1; Path=/; Domain=.it315.org
①建立两个具有相同域名的主机名和配置相应的虚拟主机。
②设置自动登录程序的Cookie的domain属性:
③Set-Cookie2:name=xxxxx; path=/; domain=itcast.com(我们要把cookies的path属性设置成“/”。在指定路径的时候,凡是来自同一服务器,URL里有相同路径的所有WEB页面都可以共享cookies。我们可以把domain属性设置成“itcast.com”,并把path属性设置成“/”)
④将Web应用发布到两个虚拟主机下,进行测试访问。
⑤注销Cookie时,也必须按照生成该Cookie时的情况设置domain属性,浏览器才会真正注销这个Cookie。
2.通过专用的代理服务器进行登录,如CAS和OpenSSO
单点登录_第2张图片
3.CAS工作流程
根据上图①是用户通过浏览器访问SSO客户端(SSO 客户端发送请求访问应用系统提供的服务资源),②③系统定向认证(SSO 客户端会重定向用户请求到 SSO 服务器),④⑤用户认证(用户在SSO服务端进行身份认证),⑥⑦认证成功后,CAS生成cookie(叫TGC),写入浏览器,同时生成一个TGT(ticket granting ticket)对象,再根据TGT发放票据ST(service ticket),并且重定向用户到CAS Client(附带刚才产生的ServiceTicket), Service Ticket 是不可以伪造的⑧⑨⑩拿着ST去 CAS Server验证一下,验证成功返回用户信息。
注:收到ST后,为什么还要验证呢?
因为CAS知道这个用户已经登录过了,但是对于这个项目来说,我并不知道这个用 户已经登录过了,故需要验证
关键术语:http://blog.csdn.net/matthewei6/article/details/50769670

三、CAS服务器
该cas服务端版本为4.2.7,将cas.war解压到tomcat中
可以将项目导入到eclipse中

Eclipse中新建一个WebProject
将其内容拷贝到新建的WebProject中即可(classes目录中的properties文件和log4j.xml拷到src即可)
单点登录_第3张图片

1.此次使用http协议,取消https :
①cas.properties 修改两个地方

# Decides whether SSO cookie should be created only under secure connections.
 tgc.secure=false

# Decides whether SSO Warning cookie should be created only under secure connections.
 warn.cookie.secure=false

②casLoginView.jsp这个jsp注释一段代码

file="includes/top.jsp" />

<%--
    <div id="msg" class="errors">
        

"screen.nonsecure.title" />

"screen.nonsecure.message" />

div> if>--%>

③HTTPSandIMAPS-10000001.json 中增加http的service

{
  "@class" : "org.jasig.cas.services.RegexRegisteredService",
  "serviceId" : "^(https|imaps|http)://.*",
  "name" : "HTTPS and IMAPS",
  "id" : 10000001,
  "description" : "This service definition authorized all application urls that support HTTPS and IMAPS protocols.",
  "proxyPolicy" : {
    "@class" : "org.jasig.cas.services.RefuseRegisteredServiceProxyPolicy"
  },
  "evaluationOrder" : 10000,
  "usernameAttributeProvider" : {
    "@class" : "org.jasig.cas.services.DefaultRegisteredServiceUsernameProvider"
  },
  "logoutType" : "BACK_CHANNEL",
  "attributeReleasePolicy" : {
    "@class" : "org.jasig.cas.services.ReturnAllowedAttributeReleasePolicy",
    "principalAttributesRepository" : {
      "@class" : "org.jasig.cas.authentication.principal.DefaultPrincipalAttributesRepository"
    },
    "authorizedToReleaseCredentialPassword" : false,
    "authorizedToReleaseProxyGrantingTicket" : false
  },
  "accessStrategy" : {
    "@class" : "org.jasig.cas.services.DefaultRegisteredServiceAccessStrategy",
    "enabled" : true,
    "ssoEnabled" : true
  }
}

2.修改cas.properties路径

修改war包中的propertyFileConfigurer.xml这个文件即可

3.单点登录之cas4.2.7服务端数据库配置
参考此链接:http://blog.csdn.net/pucao_cug/article/details/69062607
在deployerConfigContext.xml配置文件中屏蔽掉

 

在deployerConfigContext.xml配置文件中添加

id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"   autowire="byName">   
        "MD5"/>
    

     id="queryDatabaseAuthenticationHandler" name="primaryAuthenticationHandler" class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">  
        <property name="passwordEncoder" ref="MD5PasswordEncoder"/>
    
    <alias name="dataSource" alias="queryDatabaseDataSource" />

    id="primaryPrincipalResolver"  
        class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver" >
       <property name="attributeRepository" ref="attributeRepository" />  
    

id="dataSource"
      class="com.mchange.v2.c3p0.ComboPooledDataSource"
      p:driverClass="${database.driverClass}"
      p:jdbcUrl="${database.url}"
      p:user="${database.user}"
      p:password="${database.password}"
      p:initialPoolSize="${database.pool.minSize}"
      p:minPoolSize="${database.pool.minSize}"
      p:maxPoolSize="${database.pool.maxSize}"
      p:maxIdleTimeExcessConnections="${database.pool.maxIdleTime}"
      p:checkoutTimeout="${database.pool.maxWait}"
      p:acquireIncrement="${database.pool.acquireIncrement}"
      p:acquireRetryAttempts="${database.pool.acquireRetryAttempts}"
      p:acquireRetryDelay="${database.pool.acquireRetryDelay}"
      p:idleConnectionTestPeriod="${database.pool.idleConnectionTestPeriod}"
      p:preferredTestQuery="${database.pool.connectionHealthQuery}" />

在 cas.properties新增:

database.driverClass=com.mysql.jdbc.Driver
database.url=jdbc:mysql://127.0.0.1:3306/cas?useUnicode=true&;characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
database.user=dddd
database.password=jicc
database.pool.minSize=6
database.pool.maxSize=18
database.pool.maxWait=10000
database.pool.maxIdleTime=120
database.pool.acquireIncrement=6
database.pool.idleConnectionTestPeriod=30
database.pool.connectionHealthQuery=select 1
database.pool.acquireRetryAttempts=5
database.pool.acquireRetryDelay=2000

以上配置完成之后就可以使用tomcat将服务跑起来了。

四、客户端配置

1 新建项目
用Eclipse快速新建两个maven的webapp项目

2 配置项目
1 pom.xml
整合cas,肯定得用到cas的代码吧,所以在pom中引入cas客户端:

<dependency>
    <groupId>org.jasig.cas.clientgroupId>
    <artifactId>cas-client-coreartifactId>
    <version>3.4.1version>
dependency>
<dependency>
    <groupId>log4jgroupId>
    <artifactId>log4jartifactId>
    <version>1.2.16version>
dependency>

2 web.xml 配置

<listener>
    <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListenerlistener-class>
  listener>
  <filter>
    <filter-name>casSingleSignOutFilterfilter-name>
    <filter-class>org.jasig.cas.client.session.SingleSignOutFilterfilter-class>
    <init-param>
      <param-name>casServerUrlPrefixparam-name>
      <param-value>http://www.marsercas.com:8080/param-value>
    init-param>
  filter>
  <filter-mapping>
    <filter-name>casSingleSignOutFilterfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>
  <filter>
    <filter-name>CASFilterfilter-name>
    <filter-class>org.jasig.cas.client.authentication.AuthenticationFilterfilter-class>
    <init-param>
      <param-name>casServerLoginUrlparam-name>
      <param-value>http://www.marsercas.com:8080/loginparam-value>
    init-param>
    <init-param>
      <param-name>serverNameparam-name>
      <param-value>http://www.marsermail.com:8080param-value>
    init-param>
    <init-param>
      <param-name>useSessionparam-name>
      <param-value>trueparam-value>
    init-param>
    <init-param>
      <param-name>redirectAfterValidationparam-name>
      <param-value>trueparam-value>
    init-param>
    <init-param>
      <param-name>ignorePatternparam-name>
      <param-value>/staticres/css/|/staticres/js/param-value>
    init-param>
  filter>
  <filter-mapping>
    <filter-name>CASFilterfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>
  <filter>
    <filter-name>ticketValidationFilterfilter-name>
    <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
        filter-class>
    <init-param>
      <param-name>casServerUrlPrefixparam-name>
      <param-value>http://www.marsercas.com:8080/param-value>
    init-param>
    <init-param>
      <param-name>serverNameparam-name>
      <param-value>http://www.marsermail.com:8080param-value>
    init-param>
  filter>
  <filter-mapping>
    <filter-name>ticketValidationFilterfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>
  <filter>
    <filter-name>casHttpServletRequestWrapperFilterfilter-name>
    <filter-class>
            org.jasig.cas.client.util.HttpServletRequestWrapperFilter
        filter-class>
  filter>
  <filter-mapping>
    <filter-name>casHttpServletRequestWrapperFilterfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>
  <filter>
    <filter-name>casAssertionThreadLocalFilterfilter-name>
    <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilterfilter-class>
  filter>
  <filter-mapping>
    <filter-name>casAssertionThreadLocalFilterfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>

以上代码中 http://www.marsercas.com是我部署的cas服务器,http://www.marsermail.com:8080是客户端。当你在页面上访问http://www.marsermail.com:8080就会重定向到服务器
http://www.marsercas.com:8080/login?service=http%3A%2F%2Fwww.marsermail.com%3A8080%2F然后就进行登录,验证成功之后就可以单点登录了。

五、验证成功之后返回更多的值
从cas server登录成功后,默认只能从cas server得到用户名。但程序中也可能遇到需要得到更多如姓名,手机号,email等更多用户信息的情况。
1、首先需要配置属性attributeRepository
WEB-INF目录找到 deployerConfigContext.xml文件,同时配置 attributeRepository

<bean id= "attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao" >   
        <constructor-arg index= "0" ref ="dataSource"/>    
         <constructor-arg index= "1" value ="select *  from  t_user  where {0} and  valid=true" />  
        <property name= "queryAttributeMapping" >     
            <map>  
                
                <entry key= "username" value ="account" />  
            map>      
        property>  
        <property name="resultAttributeMapping" >   
            <map>  
                                 
                 <entry key="account" value ="account"/>    
                 <entry key="id" value="id" /> 
                 <entry key="valid" value="valid" />  
            map>    
        property>    
    bean >  

切记:查询出来的字段名中间不能使用 _ (下划线),否则获取不到数据,如 cell_phone 需要 设置别名为 cellPhone.queryAttributeMapping是组装sql用的查询条件属性,上述配置后,结合封装成查询sql就是
select* from userinfo where loginname=#username#resultAttributeMapping是sql执行完毕后返回的结构属性, key对应数据库字段,value对应客户端获取参数。如果要组装多个查询条件,需要加上下面这个,默认为AND.

<property name="queryType">  
    <value>ORvalue>  
property> 

2.修改casServiceValidationSuccess.jsp

WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp.在server验证成功后,这个页面负责生成与客户端交互的xml信息,在默认的casServiceValidationSuccess.jsp中,只包括用户名,并不提供其他的属性信息,因此需要对页面进行扩展。如下:

<%@ page session="false" contentType="application/xml; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>    
        <cas:authenticationSuccess>    
            <cas:user>${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)}cas:user>  

            <c:if test="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes) > 0}">  
                <cas:attributes>  
                    <c:forEach var="attr" items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}">  
                        <cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}cas:${fn:escapeXml(attr.key)}>    
                    c:forEach>  
                cas:attributes>  
            c:if>  

            <c:if test="${not empty pgtIou}">    
                <cas:proxyGrantingTicket>${pgtIou}cas:proxyGrantingTicket>  
            c:if>    
            <c:if test="${fn:length(assertion.chainedAuthentications) > 1}">  
                <cas:proxies>    
                    <c:forEach var="proxy" items="${assertion.chainedAuthentications}" varStatus="loopStatus" begin="0" end="${fn:length(assertion.chainedAuthentications)-2}" step="1">    
                        <cas:proxy>${fn:escapeXml(proxy.principal.id)}cas:proxy>    
                    c:forEach>  
                cas:proxies>  
            c:if>  
        cas:authenticationSuccess>  
    cas:serviceResponse> 

配置完毕!
文件资源:应用架包
http://download.csdn.net/download/marser1234/10213225

你可能感兴趣的:(单点登录)