單點登陸:spring-security-cas

  單點登陸Single Sign On),簡稱爲 SSO,是目前比較流行的企業業務整合的解決方案之一。SSO的定義是在多個應用系統中,用戶只須要登陸一次就能夠訪問全部相互信任的應用系統css

Centos7安裝cas系統html

  (1) 上傳cas.war到Centos機器的tomcat/webapps目錄下前端

  (2) 端口修改java

vim /usr/local/tomcat/apache-tomcat-7.0.52/conf/web.xml

vim /usr/local/tomcat/apache-tomcat-7.0.52/webapps/cas/WEB-INF/cas.properties

   (3) 去除https認證mysql

    1) 修改casWEB-INF/deployerConfigContext.xmlweb

vim /usr/local/tomcat/apache-tomcat-7.0.52/webapps/cas/WEB-INF/deployerConfigContext.xml

    2) 修改cas/WEB-INF/spring-configuration/ticketGrantingTicketCookieGenerator.xmlspring

    參數p:cookieSecure="true",同理爲HTTPS驗證相關,TRUE爲採用HTTPS驗證,FALSE爲不採用https驗證。sql

    參數p:cookieMaxAge="-1",是COOKIE的最大生命週期,-1爲無生命週期,即只在當前打開的窗口有效,關閉或從新打開其它窗口,仍會要求驗證。能夠根據須要修改成大於0的數字,好比3600等,意思是在3600秒內,打開任意窗口,都不須要驗證express

vim /usr/local/tomcat/apache-tomcat-7.0.52/webapps/cas/WEB-INF/spring-configuration/ticketGrantingTicketCookieGenerator.xml 

    3) 修改casWEB-INF/spring-configuration/warnCookieGenerator.xmlapache

vim /usr/local/tomcat/apache-tomcat-7.0.52/webapps/cas/WEB-INF/spring-configuration/warnCookieGenerator.xml

  (4) cas認證數據源配置

    1) 修改cas服務端中web-infdeployerConfigContext.xml ,添加以下配置

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
              p:driverClass="com.mysql.jdbc.Driver"  
              p:jdbcUrl="jdbc:mysql://127.0.0.1:3306/db?characterEncoding=utf8"  
              p:user="user"  
              p:password="password" /> 
<bean id="passwordEncoder" 
class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"  
        c:encodingAlgorithm="MD5"  
        p:characterEncoding="UTF-8" />  
<bean id="dbAuthHandler"  
          class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"  
          p:dataSource-ref="dataSource"  
          p:sql="select password from tb_user where username = ?"  
          p:passwordEncoder-ref="passwordEncoder"/>

    2)

註釋:<entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" />
添加:<entry key-ref="dbAuthHandler" value-ref="primaryPrincipalResolver"/>
搜索定位:在瀏覽模式下:/<entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" />

    3) 導入jar包

cp -r c3p0-0.9.1.2.jar /usr/local/tomcat/apache-tomcat-7.0.52/webapps/cas/WEB-INF/lib
cp -r cas-server-support-jdbc-4.0.0.jar /usr/local/tomcat/apache-tomcat-7.0.52/webapps/cas/WEB-INF/lib
cp -r mysql-connector-java-5.1.32.jar /usr/local/tomcat/apache-tomcat-7.0.52/webapps/cas/WEB-INF/lib

   (5) 替換cas登陸頁面

    1) 將css  js等文件夾拷貝到  cas目錄下

    2) 將工程登陸頁拷貝到cas系統下WEB-INF\view\jsp\default\ui 目錄下,並重命名爲casLoginView.jsp(先重命名cas系統原casLoginView.jsp)

    3) 添加指令

<%@ page pageEncoding="UTF-8" %>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

    4) 修改form標籤

<form:form method="post" id="fm1" commandName="${commandName}" htmlEscape="true" class="sui-form">
......
</form:form>

    5) 修改登陸框

<form:input id="username" tabindex="1" 
    accesskey="${userNameAccessKey}" path="username" autocomplete="off" htmlEscape="true" 
    placeholder="郵箱/用戶名/手機號" class="span2 input-xfat" />
<form:password  id="password" tabindex="2" path="password" 
      accesskey="${passwordAccessKey}" htmlEscape="true" autocomplete="off" 
      placeholder="請輸入密碼" class="span2 input-xfat"   />

    6) 修改登陸按鈕

<input type="hidden" name="lt" value="${loginTicket}" />
<input type="hidden" name="execution" value="${flowExecutionKey}" />
<input type="hidden" name="_eventId" value="submit" />
<input class="sui-btn btn-block btn-xlarge btn-danger" accesskey="l" value="登錄" type="submit" />

    7) 錯誤提示,在form內表單添加

<form:errors path="*" id="msg" cssClass="errors" element="div" htmlEscape="false" />

     8) 修改錯誤提示

vim /usr/local/tomcat/apache-tomcat-7.0.52/webapps/cas/WEB-INF/cas-servlet.xml

     9) 在messages_zh_CN.properties添加如下內容

vim /usr/local/tomcat/apache-tomcat-7.0.52/webapps/cas/WEB-INF/classes/messages_zh_CN.properties
authenticationFailure.AccountNotFoundException=\u7528\u6237\u4E0D\u5B58\u5728. authenticationFailure.FailedLoginException=\u5BC6\u7801\u9519\u8BEF.

 spring-security整合cas  

  (1) 添加依賴

        <!-- spring安全框架 -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
<!-- cas --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-cas</artifactId> </dependency> <dependency> <groupId>org.jasig.cas.client</groupId> <artifactId>cas-client-core</artifactId> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> </exclusion> </exclusions> </dependency>

   (2) 受權認證類

import java.util.ArrayList;
import java.util.List;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class UserDetailServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("UserDetailsServiceImpl : " + username);    
        // 角色受權
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
        authorities.add(authority);        
        return new User(username, "", authorities);
    }
}

   (3) spring-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

    <context:property-placeholder location="classpath:properties/*.properties" />

    <!-- 如下頁面不被攔截 -->
    <http pattern="/register.html" security="none"></http>
    <http pattern="/user/add.do" security="none"></http><!-- 放行註冊請求 -->
    <http pattern="/user/sendVCode.do" security="none"></http><!-- 放行註冊請求 -->
    <http pattern="/css/**" security="none"></http>
    <http pattern="/img/**" security="none"></http>
    <http pattern="/js/**" security="none"></http>
    <http pattern="/plugins/**" security="none"></http>
  <!-- (1)
   此配置是跳過security校驗,因此:SecurityContextHolder.getContext().getAuthentication() = null
   <http pattern="/cart/*.do" security="none"></http> -->
<!-- spring-security整合CAS單點登陸系統 --> <!-- entry-point-ref 入口點引用 --> <http use-expressions="false" entry-point-ref="casProcessingFilterEntryPoint">      <!-- (2)
      注入匿名訪問的角色 -->
      <intercept-url pattern="/cart/*.do" access="IS_AUTHENTICATED_ANONYMOUSLY" />

     <intercept-url pattern="/**" access="ROLE_USER" /> <csrf disabled="true" /> <!-- custom-filter爲過濾器, position 表示將過濾器放在指定的位置上,before表示放在指定位置以前 ,after表示放在指定的位置以後 --> <custom-filter ref="casAuthenticationFilter" position="CAS_FILTER" /> <custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER" /> <custom-filter ref="singleLogoutFilter" before="CAS_FILTER" /> </http> <!-- CAS入口點 開始 --> <beans:bean id="casProcessingFilterEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint"> <!-- 單點登陸服務器登陸URL --> <beans:property name="loginUrl" value="http://127.0.0.1:8080/cas/login" /> <beans:property name="serviceProperties" ref="serviceProperties" /> </beans:bean> <beans:bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties"> <!--service 配置自身工程的根地址+/login/cas --> <beans:property name="service" value="http://localhost:9107/login/cas" />
</beans:bean> <!-- CAS入口點 結束 --> <!-- 認證過濾器 開始 --> <beans:bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter"> <beans:property name="authenticationManager" ref="authenticationManager" /> </beans:bean> <!-- 認證管理器 --> <authentication-manager alias="authenticationManager"> <authentication-provider ref="casAuthenticationProvider"> </authentication-provider> </authentication-manager> <!-- 認證提供者 --> <beans:bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider"> <beans:property name="authenticationUserDetailsService"> <beans:bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper"> <beans:constructor-arg ref="userDetailService" /> </beans:bean> </beans:property> <beans:property name="serviceProperties" ref="serviceProperties" /> <!-- ticketValidator 爲票據驗證器 --> <beans:property name="ticketValidator"> <beans:bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator"> <beans:constructor-arg index="0" value="http://127.0.0.1:8080/cas" />
</beans:bean> </beans:property> <beans:property name="key" value="an_id_for_this_auth_provider_only" /> </beans:bean> <!-- 認證類 --> <beans:bean id="userDetailService" class="com.xxx.user.service.impl.UserDetailServiceImpl" /> <!-- 認證過濾器 結束 --> <!-- 單點登出 開始 --> <beans:bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter" /> <beans:bean id="requestSingleLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
     <!-- 退出登陸後跳轉的路徑 --> <beans:constructor-arg value="http://127.0.0.1:8080/cas/logout?service=http://localhost:9107" /> <beans:constructor-arg> <beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" /> </beans:constructor-arg> <beans:property name="filterProcessesUrl" value="/logout/cas" /> </beans:bean> <!-- 單點登出 結束 --> </beans:beans>

   (4) web.xml

    <welcome-file-list>
        <welcome-file>home-index.html</welcome-file>
    </welcome-file-list>

    <!-- post亂碼過濾器 -->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 前端控制器 -->
    <servlet>
        <servlet-name>xxx-user-web</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- contextConfigLocation不是必須的, 若是不配置contextConfigLocation, springmvc的配置文件默認在:WEB-INF/servlet的name+"-servlet.xml" -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>xxx-user-web</servlet-name>
        <!-- 攔截全部請求jsp除外 -->
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    <!-- spring安全框架 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/spring-security.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

   (5) 頁面登出代碼

<span class="safe"> <a href="/logout/cas">退出登陸 </a></span>

  (6) 獲取登陸名

@RestController
public class UserController {
    @RequestMapping("/findLoginUser")
    public void  findLoginUser(){
        String name = SecurityContextHolder.getContext().getAuthentication().getName();
        System.out.println(name);        
    }    
}
相關文章
相關標籤/搜索