【试水CAS-4.0.3】第05节_CAS服务端自定义返回的用户信息

/**
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @see CAS服务端自定义返回的用户信息
 * @see 返回的用户信息是在deployerConfigContext.xml中的<bean id="attributeRepository">配置的
 * @see 既然想自定义返回的用户信息,那继承org.jasig.services.persondir.support.StubPersonAttributeDao就好了
 * @see 1.创建com.msxf.sso.authentication extends StubPersonAttributeDao并复写getPerson()方法
 * @see   使用@Component(value="attributeRepository")定义它的BeanID
 * @see 2.注释deployerConfigContext.xml中的<bean id="attributeRepository">和<util:map id="attrRepoBackingMap">配置
 * @see 3.修改\WEB-INF\view\jsp\protocol\2.0\casServiceValidationSuccess.jsp(不要改3.0下面的)
 * @see 具体改动,详见下方贴出的代码
 * @see 另外,返回给客户端的相关信息是由org.jasig.services.persondir.IPersonAttributeDao接口定义的
 * @see StubPersonAttributeDao就是IPersonAttributeDao的实现之一,其它实现如SingleRowJdbcPersonAttributeDao/LdapPersonAttributeDao
 * @see 所以也可在deployerConfigContext.xml中配置<bean id="attributeRepository">的实现为SingleRowJdbcPersonAttributeDao
 * @see <bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
 * @see 个人觉得这样不是很灵活,所以就不贴示例代码了,有情趣的可以看http://pkaq.github.io/2015/01/14/CAS/
 * @see ------------------------------------------------------------------------------------------------------------------------
 * @create 2015-7-20 下午4:59:08
 * @author 玄玉<http://blog.csdn.net/jadyer>
 */

下面是自定义的控制返回的用户信息的UserStubPersonAttributeDao.java

package com.msxf.sso.authentication;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.jasig.services.persondir.IPersonAttributes;
import org.jasig.services.persondir.support.AttributeNamedPersonImpl;
import org.jasig.services.persondir.support.StubPersonAttributeDao;
import org.springframework.stereotype.Component;

import com.msxf.sso.model.User;

/**
 * 自定义的返回给客户端相关信息
 * @create 2015-7-18 下午5:52:56
 * @author 玄玉<http://blog.csdn.net/jadyer>
 */
@Component(value="attributeRepository")
public class UserStubPersonAttributeDao extends StubPersonAttributeDao {
	@Resource
	private UserDaoJdbc userDaoJdbc;

	@Override
	public IPersonAttributes getPerson(String uid) {
		Map<String, List<Object>> attributes = new HashMap<String, List<Object>>();
		try {
			User user = userDaoJdbc.getByUsername(uid);
			attributes.put("userId", Collections.singletonList((Object)user.getUsercode()));
			attributes.put("username", Collections.singletonList((Object)user.getUsername()));
			attributes.put("usernamePlain", Collections.singletonList((Object)URLEncoder.encode(user.getUsernamePlain(), "UTF-8")));
			attributes.put("blogURL", Collections.singletonList((Object)"http://blog.csdn.net/jadyer"));
			attributes.put("blogger", Collections.singletonList((Object)URLEncoder.encode("玄玉", "UTF-8")));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return new AttributeNamedPersonImpl(attributes);
	}
}

下面是用到的查询数据库的UserDaoJdbc.java

package com.msxf.sso.authentication;

import java.sql.ResultSet;
import java.sql.SQLException;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import com.msxf.sso.model.User;

@Repository
public class UserDaoJdbc {
	private static final String SQL_USER_VERIFY = "SELECT COUNT(*) FROM permission_operator WHERE operator_login=? AND operator_pwd=SHA1(?)";
	private static final String SQL_USER_GET = "SELECT * FROM permission_operator WHERE operator_login=?";

	private JdbcTemplate jdbcTemplate;

	@Resource
	public void setDataSource(DataSource dataSource){
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	/**
	 * 验证用户名和密码是否正确
	 * @create 2015-7-17 下午3:56:54
	 * @author 玄玉<http://blog.csdn.net/jadyer>
	 */
	public boolean verifyAccount(String username, String password){
		try{
			return 1==this.jdbcTemplate.queryForObject(SQL_USER_VERIFY, new Object[]{username, password}, Integer.class);
		}catch(EmptyResultDataAccessException e){
			return false;
		}
	}

	/**
	 * 根据用户名获取用户信息
	 * @create 2015-7-20 上午10:40:54
	 * @author 玄玉<http://blog.csdn.net/jadyer>
	 */
	public User getByUsername(String username){
		try{
			return (User)this.jdbcTemplate.queryForObject(SQL_USER_GET, new Object[]{username}, new UserRowMapper());
		}catch(EmptyResultDataAccessException e){
			return new User();
		}
	}
}

class UserRowMapper implements RowMapper<User> {
	@Override
	public User mapRow(ResultSet rs, int index) throws SQLException {
		User user = new User();
		user.setUsercode(rs.getString("operator_code"));
		user.setUsername(rs.getString("operator_login"));
		user.setUsernamePlain(rs.getString("operator_name"));
		return user;
	}
}

下面是用到的User.java

package com.msxf.sso.model;

public class User {
	private String usercode;
	private String username;
	private String usernamePlain;

	public String getUsercode() {
		return usercode;
	}
	public void setUsercode(String usercode) {
		this.usercode = usercode;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getUsernamePlain() {
		return usernamePlain;
	}
	public void setUsernamePlain(String usernamePlain) {
		this.usernamePlain = usernamePlain;
	}
}

下面是deployerConfigContext.xml的修改部分

<!-- 注释掉默认的attributeRepository实现,采用自定义的UserStubPersonAttributeDao -->
   <!--
   <bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao"
           p:backingMap-ref="attrRepoBackingMap" />

   <util:map id="attrRepoBackingMap">
       <entry key="uid" value="uid" />
       <entry key="eduPersonAffiliation" value="eduPersonAffiliation" />
       <entry key="groupMembership" value="groupMembership" />
   </util:map>
 -->

下面是\WEB-INF\view\jsp\protocol\2.0\casServiceValidationSuccess.jsp

<%--

    Licensed to Jasig under one or more contributor license
    agreements. See the NOTICE file distributed with this work
    for additional information regarding copyright ownership.
    Jasig licenses this file to you under the Apache License,
    Version 2.0 (the "License"); you may not use this file
    except in compliance with the License.  You may obtain a
    copy of the License at the following location:

      http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.

--%>
<%@ 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.primaryAuthentication.principal.id)}</cas:user>
        <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>
        <%--
		新增部分如下:CASServer验证成功后,该页面负责生成与客户端交互的XML信息
		默认的casServiceValidationSuccess.jsp中只包括用户名,并不提供其他的属性信息,因此需要对该页面进行扩展
        --%>
		<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>
	</cas:authenticationSuccess>
</cas:serviceResponse>

最后是客户端获取服务端返回的自定义用户信息的index.jsp

<%@ page pageEncoding="UTF-8"%>
<%@ page import="java.util.Map"%>
<%@ page import="java.net.URLDecoder"%>
<%@ page import="org.jasig.cas.client.util.AssertionHolder"%>
<%@ page import="org.jasig.cas.client.authentication.AttributePrincipal"%>

<body style="background-color:#CBE0C9;">
	<span style="color:red; font-size:32px; font-weight:bold;">客户端登录成功</span>
</body>

<hr size="2">

<%
	AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal();
	Map<String, Object> attributes = principal.getAttributes();
	out.print("principal.getName()=" + principal.getName() + "<br/>");
	out.print("request.getRemoteUser()=" + request.getRemoteUser() + "<br/>");
	out.print("登录用户:" + attributes.get("userId") + "<br/>");
	out.print("登录时间:" + AssertionHolder.getAssertion().getAuthenticationDate() + "<br/>");
	out.print("-----------------------------------------------------------------------<br/>");
	for(Map.Entry<String,Object> entry : attributes.entrySet()){
		//服务端返回中文时需要encode,客户端接收显示中文时需要decode,否则会乱码
		out.print(entry.getKey() + "=" + URLDecoder.decode(entry.getValue().toString(), "UTF-8") + "<br/>");
	}
	out.print("-----------------------------------------------------------------------<br/>");
	Map<String, Object> attributes22 = AssertionHolder.getAssertion().getAttributes();
	for(Map.Entry<String,Object> entry : attributes22.entrySet()){
		out.print(entry.getKey() + "=" + entry.getValue() + "<br/>");
	}
	out.print("-----------------------------------------------------------------------<br/>");
	Map<String, Object> attributes33 = AssertionHolder.getAssertion().getPrincipal().getAttributes();
	for(Map.Entry<String,Object> entry : attributes33.entrySet()){
		out.print(entry.getKey() + "=" + entry.getValue() + "<br/>");
	}
%>

关于客户端如何配置(包括通过Spring),详见下一篇博文。

今天头疼还发烧,明天再发客户端的配置方法。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-26 06:01:47

【试水CAS-4.0.3】第05节_CAS服务端自定义返回的用户信息的相关文章

【试水CAS-4.0.3】第04节_CAS服务端通过数据库认证用户

本文源码下载:http://download.csdn.net/detail/jadyer/8911139 /** * @see ------------------------------------------------------------------------------------------------------------------------ * @see CAS服务端通过数据库认证用户 * @see 实现方式有两种,一是自己写数据库获取用户名密码再认证的类,一是借助C

【试水CAS-4.0.3】第09节_CAS服务端RememberMe

本文源码下载:http://download.csdn.net/detail/jadyer/8940967 /** * @see ------------------------------------------------------------------------------------------------------------------------ * @see 先介绍一下CAS-4.0.3服务端的来自cas.properties中的一些其它配置项 * @see 1.cas.

【试水CAS-4.0.3】第06节_CAS服务端配置HTTPS

/** * @see CAS服务端配置HTTPS * @see ------------------------------------------------------------------------------------------------------------------------ * @see 1.生成KeyStore * @see 1.1.D:\>keytool -genkey -alias XuanyuKeyStore -keyalg RSA -validity 10

【试水CAS-4.0.3】第03节_CAS服务端登录页添加验证码

/** * @see ------------------------------------------------------------------------------------------------------------------------ * @see CAS登录页添加验证码 * @see 0.这年头验证码一般用来防止帐号被暴力破解,如果我们的系统是走专线的,也就是说放在内网,那完全没必要搞验证码 * @see 1.由于CAS使用了Spring Web Flow框架,所以

【试水CAS-4.0.3】第02节_CAS服务端登录页个性化

完整版见https://jadyer.github.io/2015/07/16/sso-cas-login-diy/ /** * @see ------------------------------------------------------------------------------------------------------------------------ * @see CAS个性登录页 * @see 0.cas的页面显示控制是集中在\WEB-INF\cas.propert

【试水CAS-4.0.3】第01节_CAS服务端搭建及导入源码到MyEclipse

/** * @see ------------------------------------------------------------------------------------------------------------------------ * @see CAS(Central Authentication Service) * @see 官网:https://www.apereo.org/projects/cas * @see 源码:https://github.com/

Mvc4单点登录之四 配置Cas服务端,返回更多的用户信息!

        .Net单点登录详解 (SSO)        Mvc4单点登录之一Cas简单介绍        Mvc4单点登录之二 Cas server端配置            Mvc4单点登录之三Cas 客户端配置            前几篇博客大致的介绍了,cas的使用,在这篇博客当中,将为大家介绍一下如何配置服务端,让用户登录之后,返回更多的用户信息! 一.首先需要配置属性attributeRepository 首先,你需要到WEB-INF目录找到 deployerConfigC

CAS单点登录学习(一):服务端搭建

下载先在网上下载cas-server-3.5.2,将里面的cas-server-webapp-3.5.2.war放到tomcat的webapps目录下. https设置cas单点登默认使用的是https,所以需要证书,由于是个人测试和学习用的,可以用JDK自带的keytool工具生成证书.2.1 用JDK生成证书:方便复制:keytool -genkey -alias mykey -keypass 123456 -keyalg RSA -validity 365 -keystore E:/cas

.net core 3.0 Signalr - 07 业务实现-服务端 自定义管理组、用户、连接

## Hub的管理 - 重写OnConnectedAsync 从连接信息中获取UserId.Groups,ConnectId,并实现这三者的关系,存放于redis中 [代码请查看](https://github.com/xiexingen/CTS.Signalr/blob/master/CTS.Signalr.Server/Hubs/NotifyHub.cs) ``` C# using CTS.Signalr.Server.Cores; using CTS.Signalr.Server.Dtos