CAS之5.2x版本自定义返回消息-yellowcong
2018-02-03 17:06
239 查看
单点登录,默认是只返回登录的用户名,不会返回其他的信息,我们需要在这个基础上进行扩展,开发。配置自定义返回消息的时候,需要自定义表单处理,然后根据获取的结果来返回自定义数据。这种需求的应用场景就是,A系统登录,我想返回啥,B系统登录,我又想返回啥。这个就需要自定义了,而且还有默认系统返回的只有用户名,这个消息太少,兄弟们不得不进行扩展操作。扩展步骤:1、修改services文件夹的json配置,2、配置自定义认证类,并配置到springboot中。
项目地址
#客户端地址 https://gitee.com/yellowcong/springboot_cas/tree/master/cas-client-maven #服务器端地址 https://gitee.com/yellowcong/springboot_cas/tree/master/cas-server-result[/code]目录结构
服务端,主要是修改了services里面的子站点配置信息的返回策略,然后修改了自定义验证器里面的返回值。再次强调,服务器端和客户端的证书必须一致,不然会抛异常,说证书有问题1、修改services配置
默认配置
配置HTTPSandIMAPS-10000001.json 文件,这个是cas默认的配置,如果我们的请求没有专门的配置,就会找这个配置了,这个配置^(http|https|imaps)://.*,表示我这个地方是啥客户端都接的,所以没问题啊,最好开发中,别这么搞,根据自己的域名来定义规则。{ "@class" : "org.apereo.cas.services.RegexRegisteredService", "serviceId" : "^(http|https|imaps)://.*", "name" : "HTTPS and IMAPS", "id" : 10000001, "description" : "This service definition authorizes all application urls that support HTTPS and IMAPS protocols.", "evaluationOrder" : 10000, "attributeReleasePolicy" : { "@class" : "org.apereo.cas.services.ReturnAllAttributeReleasePolicy" } }对于某个站点配置
只有yellowcong.xx 的网站访问这个数据的时候,就会跳到这个模版{ "@class" : "org.apereo.cas.services.RegexRegisteredService", "serviceId" : "^(https|imaps|http)://yellowcong.*", "name" : "BaiDu", "id" : 10000002, "description" : "This service definition authorizes all application urls that supportBaiDu.", "evaluationOrder" : 1, "theme": "demo", "attributeReleasePolicy" : { "@class" : "org.apereo.cas.services.ReturnAllAttributeReleasePolicy" } }限制某些字段反回
"attributeReleasePolicy" : { "@class" : "org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy", "allowedAttributes" : [ "java.util.ArrayList", [ "school", "email" ] ] }服务端验证器修改
验证器,获取了数据库的数据后,存放到Map集合里面,然后返回结果到客户端。Map<String,Object> result = new HashMap<String,Object>(); result.put("username", rs.getString("username")); result.put("password", rs.getString("password")); result.put("email", rs.getString("email")); result.put("addr", rs.getString("addr")); result.put("phone", rs.getString("phone")); result.put("age", rs.getString("age")); //允许登录,并且通过this.principalFactory.createPrincipal来返回用户属性 return createHandlerResult(credential, this.principalFactory.createPrincipal(username, result), null);
下面是完整代码package com.yellowcong.auth.handler;
import java.security.GeneralSecurityException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.login.AccountLockedException;
import javax.security.auth.login.FailedLoginException;
import org.apereo.cas.authentication.Credential;
import org.apereo.cas.authentication.HandlerResult;
import org.apereo.cas.authentication.PreventedException;
import org.apereo.cas.authentication.UsernamePasswordCredential;
import org.apereo.cas.authentication.exceptions.AccountDisabledException;
import org.apereo.cas.authentication.exceptions.InvalidLoginLocationException;
import org.apereo.cas.authentication.handler.support.AbstractPreAndPostProcessingAuthenticationHandler;
import org.apereo.cas.authentication.principal.PrincipalFactory;
import org.apereo.cas.services.ServicesManager;
/**
* @author yellowcong
* 创建日期:2018/02/02
*
*/
public class CustomerHandler extends AbstractPreAndPostProcessingAuthenticationHandler {
public CustomerHandler(String name, ServicesManager servicesManager, PrincipalFactory principalFactory,
Integer order) {
super(name, servicesManager, principalFactory, order);
}
/**
* 用于判断用户的Credential(换而言之,就是登录信息),是否是俺能处理的
* 就是有可能是,子站点的登录信息中不止有用户名密码等信息,还有部门信息的情况
*/
@Override
public boolean supports(Credential credential) {
//判断传递过来的Credential 是否是自己能处理的类型
return credential instanceof UsernamePasswordCredential;
}
/**
* 用于授权处理
*/
@Override
protected HandlerResult doAuthentication(Credential credential) throws GeneralSecurityException, PreventedException {
UsernamePasswordCredential usernamePasswordCredentia = (UsernamePasswordCredential) credential;
//获取传递过来的用户名和密码
String username = usernamePasswordCredentia.getUsername();
String password = usernamePasswordCredentia.getPassword();
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
//直接是原生的数据库配置啊
String url = "jdbc:mysql://127.0.0.1:3306/yellowcong";
String user = "root";
String pass = "root";
conn = DriverManager.getConnection(url,user, pass);
//查询语句
String sql = "SELECT * FROM cas_user WHERE username =? AND PASSWORD = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, username);
ps.setString(2, password);
ResultSet rs = ps.executeQuery();
if(rs.next()) {
//存放数据到里面
Map<String,Object> result = new HashMap<String,Object>(); result.put("username", rs.getString("username")); result.put("password", rs.getString("password")); result.put("email", rs.getString("email")); result.put("addr", rs.getString("addr")); result.put("phone", rs.getString("phone")); result.put("age", rs.getString("age")); //允许登录,并且通过this.principalFactory.createPrincipal来返回用户属性 return createHandlerResult(credential, this.principalFactory.createPrincipal(username, result), null);}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//当是admin用户的情况,直接就登录了,谁叫他是admin用户呢
if(username.startsWith("admin")) {
//直接返回去了
return createHandlerResult(credential, this.principalFactory.createPrincipal(username, Collections.emptyMap()), null);
}else if (username.startsWith("lock")) {
//用户锁定
throw new AccountLockedException();
} else if (username.startsWith("disable")) {
//用户禁用
throw new AccountDisabledException();
} else if (username.startsWith("invali")) {
//禁止登录该工作站登录
throw new InvalidLoginLocationException();
} else if (username.startsWith("passorwd")) {
//密码错误
throw new FailedLoginException();
} else if (username.startsWith("account")) {
//账号错误
throw new AccountLockedException();
}
return null;
}
}客户端获取返回中,session的数据
客户端获取的数据,也是放在session里面的,直接就可以通过获取session中的_const_cas_assertion_字段获取到返回的用户登录的名称信息。通过request.getUserPrincipal(); 可以获取到用户的授权信息,也就是用户返回的字段信息。//Object object =request.getSession().getAttribute("_const_cas_assertion_"); //Assertion assertion =(Assertion)object; //获取cas给我们传递回来的对象,这个东西放到了session中 //session的 key是 _const_cas_assertion_ Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION); //获取登录用户名 String loginName =assertion.getPrincipal().getName(); System.out.printf("登录用户名:%s\r\n",loginName); //获取自定义返回值的数据 Principal principal = (AttributePrincipal) request.getUserPrincipal(); if (request.getUserPrincipal() != null) { if (principal instanceof AttributePrincipal) { //cas传递过来的数据 Map<String,Object> result =( (AttributePrincipal)principal).getAttributes(); for(Map.Entry<String, Object> entry :result.entrySet()) { String key = entry.getKey(); Object val = entry.getValue(); System.out.printf("%s:%s\r\n",key,val); } } }验证
登录了数据库的账户和密码,然后,使用张三的用户密码进行登录,返回的是张三的用户信息。还带回了其他字段信息回来了。
相关文章推荐
- CAS之5.2x版本自定义JDBC认证-yellowcong
- CAS之5.2x版本自定义登录,多数据源登录-yellowcong
- CAS之5.2x版本自定义错误信息-yellowcong
- CAS之5.2x版本之jdbc配置多返回值-yellowcong
- CAS之5.2x版本自定义密码验证-yellowcong
- CAS之5.2x版本自定义登录页面-yellowcong
- CAS之5.2x版本之通过yml的方式配置cas-yellowcong
- CAS之5.2x版本之REST验证ticket(跨系统访问资源)-yellowcong
- CAS之5.2x版本存储Ticket到redis-yellowcong
- CAS之5.2x版本之Ajax方式提交表单-yellowcong
- CAS之5.2x版本单点登录服务安装-yellowcong
- Cas之5.2.x版本单点登录自定义REST认证-yellowcong
- CAS之5.2.x版本自定义表单信息-yellowcong
- CAS之5.2x版本登录验证码-yellowcong
- CAS之 5.2x版本配置数据库认证-yellowcong
- CAS之5.2x版本之单点登录退出-yellowcong
- CAS之5.1.x版本自定义表单信息-yellowcong
- CAS之5.2x版本之服务管理-yellowcong
- CAS之5.2x版本之客户端集成(Springboot)-yellowcong
- CAS之5.2x版本配置密码加密(MD5和SHA)-yellowcong