• CAS 单点登录4.24版本 登录调用其它系统并且返回客户端用其它的用户信息改造


    1.登录调用其它系统。修改deployerConfigContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:c="http://www.springframework.org/schema/c"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:util="http://www.springframework.org/schema/util"
           xmlns:sec="http://www.springframework.org/schema/security"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.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
           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
    
        <!-- 引入配置文件 -->
    <!--     <bean id="propertyConfigurer" -->
    <!--           class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> -->
    <!--         <property name="location" value="classpath:redis.properties" /> -->
    <!--     </bean> -->
        
        <util:map id="authenticationHandlersResolvers">
            <entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
            <entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" />
        </util:map>
    
        <util:list id="authenticationMetadataPopulators">
            <ref bean="successfulHandlerMetaDataPopulator" />
            <ref bean="rememberMeAuthenticationMetaDataPopulator" />
        </util:list>
    
    
        <!-- <alias name="acceptUsersAuthenticationHandler" alias="primaryAuthenticationHandler" /> -->
        
        <!--begin 从数据库中的用户表中读取 -->
        <bean   id="callIntefaceAuthenticationHandler"   name="primaryAuthenticationHandler"    class="com.hivecas.adaptors.CallIntefaceAuthenticationHandler">  
        </bean>
          
         <alias name="userInfoPrincipalResolver" alias="primaryPrincipalResolver" />
         
    <!--     <alias name="personDirectoryPrincipalResolver" alias="primaryPrincipalResolver" /> -->
        
        <bean id="attributeRepository" class="org.jasig.services.persondir.support.NamedStubPersonAttributeDao"
              p:backingMap-ref="attrRepoBackingMap" />
              
        <util:map id="attrRepoBackingMap">
            <entry key="uid" value="uid" />
            <entry key="eduPersonAffiliation" value="eduPersonAffiliation" />
            <entry key="groupMembership" value="groupMembership" />
            <entry>
                <key><value>memberOf</value></key>
                <list>
                    <value>faculty</value>
                    <value>staff</value>
                    <value>org</value>
                </list>
            </entry>
        </util:map>
       
        <!--end  从数据库中的用户表中读取 -->
      
    
        <alias name="serviceThemeResolver" alias="themeResolver" />
    
        <alias name="jsonServiceRegistryDao" alias="serviceRegistryDao" />
    
        <!-- <alias name="defaultTicketRegistry" alias="ticketRegistry" /> -->
        <!-- 票据保存方式及有效期设置 -->
    	<alias name="redisTicketRegistry" alias="ticketRegistry" />
    <!-- 	<bean id="redisTicketRegistry" class="com.hivescm.cas.ticket.registry.RedisTicketRegistry" -->
    <!-- 	    p:client-ref="ticketRedisTemplate" -->
    <!-- 	    p:tgtTimeout="28800" -->
    <!-- 	    p:stTimeout="10"/> -->
    	  <bean id="redisTicketRegistry" class="com.hivescm.cas.ticket.registry.RedisClusterTicketRegistry"
    	    p:client-ref="redisTemplate"
    	    p:tgtTimeout="28800"
    	    p:stTimeout="1000"/>
    	<!-- redis连接池 -->
    
    <!--     jedis 配置 -->
        <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" >
    <!--         最大空闲数 -->
            <property name="maxIdle" value="${redis.maxIdle}" />
    <!--         最大建立连接等待时间 -->
            <property name="maxWaitMillis" value="${redis.maxWait}" />
    <!--         是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个 -->
            <property name="testOnBorrow" value="${redis.testOnBorrow}" />
        </bean >
    
    <!--     配置文件加载 -->
        <bean id="resourcePropertySource" class="org.springframework.core.io.support.ResourcePropertySource">
            <constructor-arg name="name" value="redis.cluster.properties"/>
            <constructor-arg name="resource" value="classpath:redis.cluster.properties"/>
        </bean>
    <!--     redisCluster配置 -->
        <bean id="redisClusterConfiguration" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
            <constructor-arg name="propertySource" ref="resourcePropertySource"/>
        </bean>
    <!--     redis服务器中心 -->
        <bean id="connectionFactory"  class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
           <constructor-arg name="clusterConfig" ref="redisClusterConfiguration"/>
            <constructor-arg name="poolConfig" ref="poolConfig"/>
            <property name="password" value="${redis.password}" />
            <property name="timeout" value="${redis.timeout}" ></property>
        </bean >
        <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
            <property name="connectionFactory" ref="connectionFactory" />
    <!--         如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!!  -->
            <property name="keySerializer" >
                <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
            </property>
            <property name="valueSerializer" >
                <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
            </property>
            <property name="hashKeySerializer">
                <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
            </property>
            <property name="hashValueSerializer">
                <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
            </property>
        </bean >
        
        <alias name="ticketGrantingTicketExpirationPolicy" alias="grantingTicketExpirationPolicy" />
    <!--     <alias name="multiTimeUseOrTimeoutExpirationPolicy" alias="serviceTicketExpirationPolicy" /> -->
        <alias name="neverExpiresExpirationPolicy" alias="serviceTicketExpirationPolicy" />
    
        <alias name="anyAuthenticationPolicy" alias="authenticationPolicy" />
        <alias name="acceptAnyAuthenticationPolicyFactory" alias="authenticationPolicyFactory" />
    
        <bean id="auditTrailManager"
              class="org.jasig.inspektr.audit.support.Slf4jLoggingAuditTrailManager"
              p:entrySeparator="${cas.audit.singleline.separator:|}"
              p:useSingleLine="${cas.audit.singleline:false}"/>
    
        <alias name="neverThrottle" alias="authenticationThrottle" />
    
        <util:list id="monitorsList">
            <ref bean="memoryMonitor" />
            <ref bean="sessionMonitor" />
        </util:list>
    
        <alias name="defaultPrincipalFactory" alias="principalFactory" />
        <alias name="defaultAuthenticationTransactionManager" alias="authenticationTransactionManager" />
        <alias name="defaultPrincipalElectionStrategy" alias="principalElectionStrategy" />
        <alias name="tgcCipherExecutor" alias="defaultCookieCipherExecutor" />
        
        
    </beans>
    

      2.CallIntefaceAuthenticationHandler

    package com.hivecas.adaptors;
    
    
    import org.apache.commons.lang3.StringUtils;
    import org.jasig.cas.authentication.HandlerResult;
    import org.jasig.cas.authentication.PreventedException;
    import org.jasig.cas.authentication.UsernamePasswordCredential;
    import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.dao.DataAccessException;
    import org.springframework.dao.IncorrectResultSizeDataAccessException;
    import org.springframework.stereotype.Component;
    import com.alibaba.fastjson.JSONObject;
    import com.hivecas.model.UsernamePasswordStrongCredential;
    import com.hivecas.util.HttpUtil;
    import com.hivescm.common.domain.DataResult;
    import javax.security.auth.login.AccountNotFoundException;
    import javax.security.auth.login.FailedLoginException;
    import javax.validation.constraints.NotNull;
    
    import java.security.GeneralSecurityException;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * 自定义请求接口验证用户登录权限
     * @author lvxt
     *
     */
    @Component("callIntefaceAuthenticationHandler")
    public class CallIntefaceAuthenticationHandler extends AbstractUsernamePasswordAuthenticationHandler {
    	
    	@NotNull
        private String requestUrl;
        @Override
        protected final HandlerResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential credential)
                throws GeneralSecurityException, PreventedException {
    
            if (StringUtils.isBlank(requestUrl)) {
                throw new GeneralSecurityException("Authentication handler is not configured correctly");
            }
    
            final String username = credential.getUsername();
            final String password = credential.getPassword();
            Map dataMap;
            UsernamePasswordStrongCredential strongCredential;
            try {
            	Map map =new HashMap();
            	map.put("loginName", username);
            	map.put("password", password);
            	String resultJsonStr=HttpUtil.postRequest(requestUrl, map);
            	DataResult data= (DataResult) JSONObject.parseObject(resultJsonStr, DataResult.class);
                if (!data.isSuccess()) {
                    throw new FailedLoginException("Password does not match value on record.");
                }
                strongCredential=(UsernamePasswordStrongCredential) credential;
                dataMap=(Map) data.getResult();
                strongCredential.setAttributes(dataMap); 
            } 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(strongCredential, this.principalFactory.createPrincipal(username,dataMap), null);
        }
        public String getRequestUrl() {
    		return requestUrl;
    	}
        @Autowired
    	public void setRequestUrl(@Value("${cas.login.auth.request.url:}") String requestUrl) {
    		this.requestUrl = requestUrl;
    	}
    }
    

      3.UsernamePasswordStrongCredential的改造,用于存入调用登录接口返回的用户信息存入map中

    package com.hivecas.model;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Size;
    
    import org.apache.commons.lang3.builder.HashCodeBuilder;
    import org.jasig.cas.authentication.UsernamePasswordCredential;
    
    public class UsernamePasswordStrongCredential extends UsernamePasswordCredential  {
    	 /** 
         * 带验证码的登录界面 
         */  
        private static final long serialVersionUID = 1L;  
        /** 验证码*/  
        @Size(min = 1, message = "required.authcode")  
        private String authcode;  
        /**登录类型
         * 1.pc登录 2 移动端登录
         */
        @NotNull  
        @Size(min = 1, message = "required.loginType")  
        private String loginType;
        /**
         * 用户返回数据
         */
        private Map<String,Object> attributes = new HashMap<>();
        
      
        public Map<String, Object> getAttributes() {
    		return attributes;
    	}
    
    	public void setAttributes(Map<String, Object> attributes) {
    		this.attributes = attributes;
    	}
    
    	public String getLoginType() {
    		return loginType;
    	}
    
    	public void setLoginType(String loginType) {
    		this.loginType = loginType;
    	}
    
    	/** 
         *  
         * @return 
         */  
        public final String getAuthcode() {  
            return authcode;  
        }  
      
        /** 
         *  
         * @param authcode 
         */  
        public final void setAuthcode(String authcode) {  
            this.authcode = authcode;  
        }  
      
        
        public UsernamePasswordStrongCredential() {
            super();
        }
    
        public UsernamePasswordStrongCredential(String userName,
                String password) {
            super(userName, password);
        }
        
        public UsernamePasswordStrongCredential(String userName,
                String password,String loginType) {
            super(userName, password);
            setLoginType(loginType);
        }
    
        @Override  
        public boolean equals(final Object o) {  
            if (this == o) {  
                return true;  
            }  
            if (o == null || getClass() != o.getClass()) {  
                return false;  
            }  
      
            final UsernamePasswordStrongCredential that = (UsernamePasswordStrongCredential) o;  
      
            if (getPassword() != null ? !getPassword().equals(that.getPassword())  
                    : that.getPassword() != null) {  
                return false;  
            }  
      
            if (getPassword() != null ? !getPassword().equals(that.getPassword())  
                    : that.getPassword() != null) {  
                return false;  
            }  
            if (authcode != null ? !authcode.equals(that.getAuthcode())  
                    : that.getAuthcode() != null)  
                return false;  
      
            return true;  
        }  
      
        @Override  
        public int hashCode() {  
            return new HashCodeBuilder().append(getUsername())  
                    .append(getPassword()).append(authcode).toHashCode();  
        }  
    }
    

      4.UserInfoPrincipalResolver.java

    package org.jasig.cas.authentication.principal;
    
    
    import javax.validation.constraints.NotNull;
    
    import org.jasig.cas.authentication.Credential;
    import org.jasig.cas.authentication.principal.DefaultPrincipalFactory;
    import org.jasig.cas.authentication.principal.Principal;
    import org.jasig.cas.authentication.principal.PrincipalFactory;
    import org.jasig.cas.authentication.principal.PrincipalResolver;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    
    import com.hivecas.model.UsernamePasswordStrongCredential;
    
    @Component("userInfoPrincipalResolver")
    public class UserInfoPrincipalResolver implements PrincipalResolver{
    	
    	 protected final transient Logger logger = LoggerFactory.getLogger(this.getClass());
    	
    	   /**
         * Factory to create the principal type.
         **/
        @NotNull
        protected PrincipalFactory principalFactory = new DefaultPrincipalFactory();
    
    	@Override
    	public Principal resolve(Credential credential) {
    		 logger.debug("Attempting to resolve a principal...");
    	     final String principalId = extractPrincipalId(credential);
    		UsernamePasswordStrongCredential  strongCredential=(UsernamePasswordStrongCredential) credential;
    		 return this.principalFactory.createPrincipal(principalId, strongCredential.getAttributes());
    	}
    
    	@Override
    	public boolean supports(Credential credential) {
    		 return credential != null && credential.getId() != null;
    	}
    	
    	  /**
         * Extracts the id of the user from the provided credential. This method should be overridden by subclasses to
         * achieve more sophisticated strategies for producing a principal ID from a credential.
         *
         * @param credential the credential provided by the user.
         * @return the username, or null if it could not be resolved.
         */
        protected String extractPrincipalId(final Credential credential) {
            return credential.getId();
        }
    
    }
    

      5.页面2.0文件下的casServiceValidationSuccess.jsp改造

    <%@ page session="false" contentType="application/xml; charset=UTF-8" %>
    <%@ page import="java.util.*, java.util.Map.Entry" %>
    <%@ 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>
    

      6.客户端测试页面index.jsp的取值效果

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ page import="org.jasig.cas.client.authentication.AttributePrincipal" %>
    <%@ page import="java.util.Map" %>
    <%@ page import="java.lang.String" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>首页</title>
    </head>
    <body>
    <div style="padding-left: 30%">
      用户名: <%=request.getAttribute("name")%>
    <h1>订单系统<%=request.getLocalPort() %></h1>
       <% Cookie[] array =request.getCookies();
       String JSESSIONID="";
       if(array!=null)
    	for(Cookie ck:array)
    	{
    		String ckName=ck.getName();
    		if(ckName.equals("JSESSIONID"))
    		{
    			JSESSIONID=ck.getValue();
    		}
    	}
       %>
       <% 
        request.setCharacterEncoding("UTF-8");
        AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
        Map attributes = principal.getAttributes();
        String id=(String)attributes.get("id"); 
        String phone=(String)attributes.get("phone"); 
        String email=(String)attributes.get("email"); 
        %>
       Cookie中的JSESSIONID=<%=JSESSIONID%><br>
           用户id=<%=id%><br>
            用户手机号=<%=phone%><br>
             用户email=<%=email%><br>
       <br><br>
       <a href="http://passport.hivescm.com/cas/logout" >退出</a>
       </div>
    </body>
    </html>
    

      

  • 相关阅读:
    负载均衡
    二叉树反转
    hashMap 和红黑树
    linux c++ 服务器编程,收藏一个测试例子
    某某音乐盒面试
    Linux中的文件i节点
    linux 文件格式压缩
    类string的构造函数、拷贝构造函数和析构函数
    计算二叉树的深度
    string转换为decimal
  • 原文地址:https://www.cnblogs.com/lvgg/p/7150450.html
Copyright © 2020-2023  润新知