Commit 01135a00 by WeiCong

增加基于人行coas单点登录功能

parent 3c702010
package cn.com.brilliance.eibs.auth;
import log.Log;
import log.LogFactory;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.dbutils.DbUtils;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.engine.spi.SessionImplementor;
import org.sss.common.impl.AbstractLoginContext;
import org.sss.common.impl.MenuItemImpl;
import org.sss.common.model.IContext.DataType;
import org.sss.common.model.IFilter;
import org.sss.common.model.IMenuItem;
import org.sss.module.hibernate.HibernateUtils;
import org.sss.module.pojo.DatabaseUtils;
import org.sss.presentation.noui.api.response.ErrorCode;
import org.sss.presentation.noui.util.NoUiUtils;
import org.sss.presentation.noui.util.StringUtil;
import org.sss.util.ContainerUtils;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.sql.*;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.Date;
/**
* LoginModule实现示例
*
* @author Jason.Hoo (latest modification by $Author: hujianxin $)
* @version $Revision: 922 $ $Date: 2014-11-19 16:05:38 +0800 (Wed, 19 Nov 2014)
* $
*/
public class DatabaseLoginContextForELCS extends AbstractLoginContext {
public static final String ERROR = "error";
final static Log log = LogFactory.getLog(DatabaseLoginContextForELCS.class);
final static String ERROR_USERNAME_PASSWORD = "error.username.password";
final static String ERROR_USER_LOCKED = "error.user.locked";
final static String ERROR_USER_EXPRIED = "error.user.expired";
final static String ERROR_SYSTEM_FAULT = "error.system.fault";
final static String STATUS_NORMAL = "0";
final static String STATUS_EXPIRED = "1";
final static String STATUS_LOCKED = "2";
final static String TYPE_VISIBLE = "0";
final static String TYPE_INVISIBLE = "1";
final static String TYPE_FREQUENT = "2";
final static String FLAG_NORMAL = "0";
final static String FLAG_INDIRECT = "1";
final static String FLAG_SKIP = "2";
final static String MENU_FREQUENT_ITEM = "menu.frequent";
final static int INDEX_INR = 1;
final static int INDEX_PNTINR = 2;
final static int INDEX_FRM = 3;
final static int INDEX_DSP = 4;
final static int INDEX_TYP = 5;
final static int INDEX_FLG = 6;
final static int INDEX_IMG = 7;
final static int INDEX_STL = 8;
final static int INDEX_CLS = 9;
final static String PWDERROR = "ESFEERROR1";
final static String VCODEERROR = "ESFEERROR2";
final static String REDISERROR = "ESFEERROR3";
final static String INITERROR = "ESFEERROR4";
private static final String loginCheck = "loginCheck.properties";
private static final String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALTHSCdzrBYyWReFrasVB+ehvfOg/34nTPPNSJsTlr0vqwvVohhqhnlBtIGE1g1//stMcAso8CevpCnN5/cOiwubzFhm1dRsyQmmkiMzH68sNx8+h87X/XeKpWIVSswc2Z3nMMV8zTDK8KhpPJwVRIQ5CqPdiYpQoDhBB5POiWPdAgMBAAECgYAxYCzI+cMK3P2QeyaQD9J05axoGpUt87YE8RDfql4Fljt1pAf9+zp3bAbNSWbdkRQamuoPYkMV09dWw7KTvBklwQe91llTF3eHXKXmI5M+NJtlfmk2aeJCwmb8LtFyIMb3ocgvni5es/jEd/UTzZvzZpbkR+aD5aiXEC/wFCNJUQJBANfQuCDO2d7MIfv36DKbGJ25oqX/e2B/GWDhNGb3F4BqN+3MkFw21MAP3OlW/nu0XgyRLVzw8pm6E6WlBR3GPGMCQQDWcHVWr7fIeQ9sLAKwhe+D4k/kPElaptxoqzMIWNcweG5fc2eMvJ5BHh081B0h4+KiLE6lgvitZU2c8aCm/TK/AkAuJ7U5TwPJYl7iRGKkcAcTtF/UoI8CVCxZS9CpNK8SB6VudhFpp1BYwwu7258RVcHHbkUFW4KG3gTVqDUv6PWBAkEAsuD6sMZB68Q4vkZ0M+Z2JzDI7h3wHuOkZtew6VyanT9I6uysy3SoGq/ROeXDK3samaeWL3DymkowFSRmnAYIpwJABliTTManT9rkQx+sahGwGKInAClxl3Po5XB8ST/75xkSobYAVaV8kgrxE4u4DJxbomBUWeT7oOOhX2vODMhuZg==";
public static int defaultSessionTimeout = 3600;
public static String defaultHomePageName = "/layout.zul";
public static String defaultHomeTransaction = "office";
public static boolean guestAccountUsed = false;
public static boolean loginOnlyOnce = true;
public static String imageNull = null;
public static String imageFrequent = null;
static int ERROR_MAX_COUNT = 5;
//用户距离上次修改密码间隔
private static Duration pwdAmeInterval = Duration.ofDays(30);
//连续多次输入密码重置
private static int maxfltcnt = 5;
static {
init();
}
protected final MenuItem menu = new MenuItem();
private String userId;
private String userRol;
private String userEty;
private Timestamp pwdamedat;
private String ukey;
private String homePageName = "/layout.zul";
private String homeTransaction = "office";
private int sessionTimeout = 3600;
private static void init() {
try {
Properties props = new Properties();
// 加载配置文件
props.load(DatabaseLoginContextForELCS.class.getClassLoader().getResourceAsStream(loginCheck));
pwdAmeInterval = Duration.ofDays(Integer.parseInt(props.getProperty("pwdAmeInterval")));
maxfltcnt = Integer.parseInt(props.getProperty("maxfltcnt"));
} catch (Throwable e) {
log.warn("初始化异常", e);
recordException(INITERROR, "初始化异常:" + e.getMessage(), "ERROR");
}
}
public static void recordException(String srvcod, String errormsg, String lev) {
Session session = HibernateUtils.openSession(null);
long count = DatabaseUtils.executeCounter(((SessionImplementor) session).connection(), "dealog");
String inr = String.format("%08d", count);
Transaction transaction = session.beginTransaction();
SQLQuery sqlQuery = session.createSQLQuery("insert into dealog(INR,CREDATTIM,SRVCOD,SRVNAM,INIFRM,RTNMSG,LOGLEV) values(?,?,?,?,?,?,?)");
sqlQuery.setString((Integer) 0, inr);
sqlQuery.setTimestamp(1, new Date());
sqlQuery.setString(2, srvcod);
sqlQuery.setString(3, srvcod);
sqlQuery.setString(4, "LOGIN");
sqlQuery.setString(5, errormsg);
sqlQuery.setString(6, lev);
sqlQuery.executeUpdate();
transaction.commit();
session.close();
log.debug("完成登陆相关异常日志记录");
}
/**
* 用户原文密码解密,先传统base64解密,然后对解密后的字符串的首位字符串进行偏移【头4 尾7】
*
* @param verifycode 验证码
* @param pwd 待解签串
* @return 解签后的字符串
*/
public static String pwdDecode(String verifycode, String pwd) {
if (StringUtil.isEmpty(pwd)) {
return "";
}
try {
// pwd = AESUtil.decryptAES(pwd,verifycode);
pwd = decrypt(pwd);
} catch (Throwable e) {
log.warn("密码解密异常:", e);
recordException(PWDERROR, "密码解密异常:" + e.getMessage(), "FATAL");
}
return pwd;
}
public static String decrypt(String pwd) throws Exception {
pwd = pwd.replaceAll("%2B", "+");
//64位解码加密后的字符串
byte[] inputByte = org.apache.commons.codec.binary.Base64.decodeBase64(pwd.getBytes("UTF-8"));
//base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte), "UTF-8");
return outStr;
}
//偏移 头4 尾7
private static String convert(String str) {
if (str.length() == 1) {
return change(str.charAt(0), 4);
} else if (str.length() == 2) {
return change(str.charAt(0), 4) + change(str.charAt(1), 7);
} else {
String btw_str = str.substring(1, str.length() - 1);
String head = change(str.charAt(0), 4);
String tail = change(str.charAt(str.length() - 1), 7);
return head + btw_str + tail;
}
}
//根据偏移量转换字符
private static String change(char ch, int offset) {
int before = ch;
int after;
//a-z
if (ch >= 97 && ch <= 122) {
if (before + offset <= 122) {
after = before + offset;
} else {
after = (before + offset) % 122 + 96;
}
return String.valueOf((char) after);
}
//A-Z
else if (ch >= 65 && ch <= 90) {
if (before + offset <= 90) {
after = before + offset;
} else {
after = (before + offset) % 90 + 64;
}
return String.valueOf((char) after);
}
//0-9
else if (ch >= 48 && ch <= 57) {
if (before + offset <= 57) {
after = before + offset;
} else {
after = (before + offset) % 57 + 47;
}
return String.valueOf((char) after);
}
return String.valueOf(ch);
}
protected boolean isVersion2() {
return false;
}
private String getVersion2Sql() {
return isVersion2() ? ",m.img,m.stl,m.stlcls" : "";
}
private String getVersion2String(ResultSet rs, int index) throws SQLException {
return isVersion2() ? rs.getString(index) : null;
}
private String getI18nValue(String key) {
return ctx.getGui().getI18nValue("eibs", key);
}
private boolean setLogon(boolean flag, String userName, String type, String logText, Statement stmt, ResultSet rs) {
DbUtils.closeQuietly(rs);
DbUtils.closeQuietly(stmt);
if (flag) {
if (loginOnlyOnce)
ctx.logout(DataType.USER_NAME, userName);
this._userName = userName;
}
if(log.isDebugEnabled()){
log.debug(String.format("%s,userName=[%s]", logText, userName));
}
errorText = flag ? "" : getI18nValue(type);
this.flag = flag;
return flag;
}
private boolean setAuth(boolean flag, Statement stmt1, ResultSet rs1, Statement stmt2, ResultSet rs2) {
DbUtils.closeQuietly(rs1);
DbUtils.closeQuietly(stmt1);
DbUtils.closeQuietly(rs2);
DbUtils.closeQuietly(stmt2);
this.authed = flag;
return flag;
}
@Override
public String getHomePageName() {
return homePageName;
}
@Override
public String getHomeTransaction() {
return homeTransaction;
}
@Override
public int getSessionTimeout() {
return sessionTimeout;
}
public String checkPassword(String userName, String verifycode, String dbPassword, String password) {
password = pwdDecode(verifycode, password);
IFilter passwordFilter = NoUiUtils.passwordFilter;
if (NoUiUtils.passwordFilter == null) {
log.warn("未在eibs.xml为NoUiUtils配置passwordFilter项");
recordException(PWDERROR, "密码校验异常:未在eibs.xml为NoUiUtils配置passwordFilter项", "FATAL");
return null;
}
if (dbPassword != null) {
dbPassword = dbPassword.trim();
}
// String encodedPassword = ContainerUtils.encodeWithSalt ? passwordFilter.encode(password, userName).trim() : passwordFilter.encode(password).trim();
// log.info("password反转回来==="+password+",userName===="+userName);
String encodedPassword = passwordFilter.encode(password, userName).trim();
// log.info("password国密解析==="+encodedPassword);
if(log.isDebugEnabled()){
log.debug("password(input/db)" + dbPassword + "\t" + encodedPassword);
}
if (!encodedPassword.equals(dbPassword))
return "[Database: NOT Match.]";
return null;
}
@Override
public boolean login(Connection conn, Map parameterMap) {
this._userName = null;
String userName = getParameter(parameterMap, "j_username");
String password = getParameter(parameterMap, "j_password");
String sendcode = getParameter(parameterMap, "j_sendcode");
String verifycode = getParameter(parameterMap, "j_verifycode");
String dncode = getParameter(parameterMap, "j_dncode");
if (userName == null || password == null || dncode == null) {
parameterMap.put(ERROR, ErrorCode.LOGIN_PARAMETER_CHECK);
return setLogon(false, userName, ERROR_USERNAME_PASSWORD, "用户名或密码为空.", null, null);
}
ResultSet rs = null;
PreparedStatement stmt = null;
try {
if (sendcode == null || verifycode == null || !sendcode.equalsIgnoreCase(verifycode)) {
log.info("验证码验证失败,待校验:" + sendcode + ",原始:" + verifycode);
parameterMap.put(ERROR, ErrorCode.LOGIN_VERIFYCODE_ERROR);
return setLogon(false, userName, ErrorCode.LOGIN_VERIFYCODE_ERROR.getCode(), ErrorCode.LOGIN_VERIFYCODE_ERROR.getMessage(), stmt, rs);
}
String sql = "SELECT inr,pwd,fltcnt,sta,etyextkey,usg,pwdamedat,ukey FROM usr WHERE nam=?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, userName);
rs = stmt.executeQuery();
if (!rs.next()) {
if (!guestAccountUsed) {
parameterMap.put(ERROR, ErrorCode.LOGIN_NON_USR);
return setLogon(false, userName, ERROR_USERNAME_PASSWORD, "系统无此用户.", stmt, rs);
}
userName = "guest";
homePageName = "/register.zul";
homeTransaction = "usrreg";
sessionTimeout = -1;
return setLogon(true, userName, null, "游客成功登录.", stmt, rs);
}
userId = rs.getString(1);
if(log.isDebugEnabled()){
log.debug("userId=" + userId);
}
String dbPassword = rs.getString(2);
int faultCount = rs.getInt(3);
String userState = rs.getString(4);// 0:正常;1:注销;2:锁定
userEty = rs.getString(5);
userRol = rs.getString(6);
pwdamedat = rs.getTimestamp(7);
ukey = rs.getString(8);
DbUtils.closeQuietly(stmt);
DbUtils.closeQuietly(rs);
String errorStr = checkPassword(userName, sendcode, dbPassword, password);
if (STATUS_LOCKED.equals(userState)) {
parameterMap.put(ERROR, ErrorCode.LOGIN_LOCK_USR);
return setLogon(false, userName, ERROR_USER_LOCKED, "用户已被锁定.", stmt, rs);
} else if (STATUS_EXPIRED.equals(userState)) {
parameterMap.put(ERROR, ErrorCode.LOGIN_EXPRIED_USR);
return setLogon(false, userName, ERROR_USER_EXPRIED, "用户已被注销.", stmt, rs);
} else if (!STATUS_NORMAL.equals(userState)) {//非0:正常;1:注销;2:锁定,不可登录,
parameterMap.put(ERROR, ErrorCode.LOGIN_STATE_ABNORMAL_ERROR);
return setLogon(false, userName, ErrorCode.LOGIN_STATE_ABNORMAL_ERROR.getCode(), ErrorCode.LOGIN_STATE_ABNORMAL_ERROR.getMessage(), stmt, rs);
} else if (!Objects.equals(ukey, dncode)) {//dn码错误
parameterMap.put(ERROR, ErrorCode.LOGIN_DN_ERROR);
return setLogon(false, userName, ErrorCode.LOGIN_DN_ERROR.getCode(), ErrorCode.LOGIN_DN_ERROR.getMessage(), stmt, rs);
} else if (Objects.nonNull(errorStr)) {
// 校验密码
sql = "UPDATE usr SET fltcnt=?,sta=?,lstfltdattim=? WHERE inr=?";
stmt = conn.prepareStatement(sql);
faultCount++;
stmt.setInt(1, faultCount);
stmt.setString(2, faultCount >= maxfltcnt ? STATUS_LOCKED : userState);
stmt.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
stmt.setString(4, userId);
stmt.execute();
conn.commit();
if (faultCount >= maxfltcnt) {
parameterMap.put(ERROR, ErrorCode.LOGIN_PWD_CHECK);
} else {
parameterMap.put(ERROR, ErrorCode.LOGIN_PWD_ERROR);
}
return setLogon(false, userName, ERROR_USERNAME_PASSWORD, String.format("密码验证失败.%s.", errorStr), stmt,
rs);
} else if (Objects.isNull(pwdamedat)) {//初次登陆
parameterMap.put(ERROR, ErrorCode.LOGIN_FIRST_LOGIN);
return setLogon(true, userName, ErrorCode.LOGIN_FIRST_LOGIN.getCode(), ErrorCode.LOGIN_FIRST_LOGIN.getMessage(), stmt, rs);
} else if (pwdamedat.toLocalDateTime().plus(pwdAmeInterval).isBefore(LocalDateTime.now())) {//超过指定时间仍为修改密码
parameterMap.put(ERROR, ErrorCode.LOGIN_PWD_AME_INTERVAL);
return setLogon(true, userName, ErrorCode.LOGIN_PWD_AME_INTERVAL.getCode(), ErrorCode.LOGIN_PWD_AME_INTERVAL.getMessage(), stmt, rs);
}
if(log.isDebugEnabled()){
log.debug("faultCount=" + faultCount);
}
sql = "UPDATE usr SET fltcnt=?,sta=?,lstdattim=? WHERE inr=?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, 0);
stmt.setString(2, STATUS_NORMAL);
stmt.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
stmt.setString(4, userId);
stmt.execute();
conn.commit();
// 监控用户返回监控页面
if ("monitor".equals(userName)) {
homePageName = "/monitor.zul";
homeTransaction = "monitor";
sessionTimeout = -1;
return setLogon(true, userName, null, "监控用户成功登录.", stmt, rs);
}
homePageName = defaultHomePageName;
homeTransaction = defaultHomeTransaction;
sessionTimeout = defaultSessionTimeout;
} catch (Throwable e) {
log.error("系统登录内部错误", e);
parameterMap.put(ERROR, ErrorCode.SYSTEM_ERROR);
return setLogon(false, userName, ERROR_SYSTEM_FAULT, "系统内部错误.", stmt, rs);
}
return setLogon(true, userName, null, "成功登录.", stmt, rs);
}
@Override
public boolean auth(Connection conn, Map parameterMap) {
if(log.isDebugEnabled()){
log.debug("正在加载当前用户菜单.");
}
String sql = "";
ResultSet rs = null;
PreparedStatement stmt = null;
ResultSet subRs = null;
PreparedStatement subStmt = null;
try {
// 进行菜单处理
Map<String, Menu> menuMap = new HashMap(); // 全部菜单
Map<String, Menu> frequentMap = new HashMap(); // 常用菜单
// 加载所有默认可访问的交易
// sql = "SELECT inr,pntinr,frm,dsp,typ,flg" + getVersion2Sql() + " FROM frm m
// WHERE typ=? OR typ=?"
sql = "select frm.inr,frm.pntinr,frm.frm,frm.dsp,frm.typ,frm.flg from frm,frr where frr.rol=? and frr.etyextkey=? and frr.frm=substr(frm.dsp,6)";
stmt = conn.prepareStatement(sql);
stmt.setString(1, userRol);
stmt.setString(2, userEty);
rs = stmt.executeQuery();
while (rs.next()) {
String id = rs.getString(INDEX_INR);
Menu menu = new Menu(id, rs.getString(INDEX_PNTINR), rs.getString(INDEX_FRM),
getVersion2String(rs, INDEX_IMG), getVersion2String(rs, INDEX_STL),
getVersion2String(rs, INDEX_CLS), rs.getString(INDEX_DSP), rs.getString(INDEX_FLG));
if (!menuMap.containsKey(id))
menuMap.put(id, menu);
if (TYPE_FREQUENT.equals(rs.getString(INDEX_TYP)))
if (!frequentMap.containsKey(id))
frequentMap.put(id, menu);
}
DbUtils.closeQuietly(stmt);
DbUtils.closeQuietly(rs);
// 进行排序
List<Menu> menus = new ArrayList(menuMap.values());
Collections.sort(menus);
List<Menu> frequents = new ArrayList(frequentMap.values());
Collections.sort(frequents);
// 通过addMenu查询并增加菜单(若未添加成功直接添加为根菜单),同时添加可访问交易
for (Menu menu : menus) {
if (!ContainerUtils.isEmpty(menu.transactionName))
this.trans.put(menu.transactionName, getI18nValue(menu.descriptionKey));
if (!FLAG_INDIRECT.equals(menu.flag) && !addMenu(this.menu, menuMap.get(menu.parentId), menu))
this.menu.add(
new MenuItem(menu.id, getI18nValue(menu.descriptionKey), menu.transactionName, menu.image));
}
// 删除菜单中为空的父项
checkMenu(this.menu);
// 添加常用菜单
MenuItem frequentItem = new MenuItem(null, getI18nValue(MENU_FREQUENT_ITEM), null, imageFrequent);
for (Menu frequent : frequents)
if (!FLAG_INDIRECT.equals(frequent.flag))
frequentItem.add(new MenuItem(frequent.id, getI18nValue(frequent.descriptionKey),
frequent.transactionName, frequent.image));
if (!frequentItem.isEmpty())
this.menu.add(frequentItem);
} catch (Exception e) {
return setAuth(false, stmt, rs, subStmt, subRs);
}
return setAuth(true, stmt, rs, subStmt, subRs);
}
public IMenuItem filterMenu(IMenuItem menuItem, String filter) {
for (IMenuItem item : menuItem) {
if (filter.equals(((MenuItem) item).id))
return item;
IMenuItem result = filterMenu(item, filter);
if (result != null)
return result;
}
return null;
}
@Override
public IMenuItem getMenu() {
if (ContainerUtils.isEmpty(menuFilter))
return menu;
return filterMenu(menu, menuFilter);
}
@Override
protected String getParameter(Map map, String key) {
if (map == null)
return null;
Object o = map.get(key);
if (o == null)
return null;
else if (o instanceof String)
return (String) o;
else if (o instanceof String[])
return ((String[]) o)[0];
else
return o.toString();
}
@Override
public Object getValue(String key) {
if ("usrinr".equals(key))
return userId;
return null;
}
@Override
public String getCustomNumber() {
return "";
}
protected void checkMenu(IMenuItem menu) {
for (int i = menu.size() - 1; i >= 0; i--) {
IMenuItem item = menu.get(i);
if (ContainerUtils.isEmpty(item.getValue())) {
if (item.isEmpty())
menu.remove(item);
else
checkMenu(item);
}
}
}
private void calculateMenu(ResultSet rs, Map<String, Menu> menuList, Map<String, Menu> frequentList,
List<String> removeMenuList, List<String> removeFrequentList, boolean flag) throws Exception { // 如果为用户信息或第一条角色信息时,直接操作待删除菜单和待删除常用菜单
// 注:多角色叠加菜单时以最大可显示的方式进行处理:可见/常用直接增加,不可见或不常用待全部角色都不可见或不常用时才处理(多角色在所有角色处理结束后再处理)
// 当flag为true时表示直接处理/直接处理待删除菜单和待删除常用菜单、false时表示需多次处理/本次不可见和不常用需要对原有待删除菜单和待删除常用菜单进行比较
List<String> _removeMenuList = flag ? removeMenuList : new ArrayList();
List<String> _removeFrequentList = flag ? removeFrequentList : new ArrayList();
while (rs.next()) {
String id = rs.getString(INDEX_INR);
String parentId = rs.getString(INDEX_PNTINR);
String type = rs.getString(INDEX_TYP);
if (TYPE_FREQUENT.equals(type)) { // 常用菜单直接增加至可见和常用
Menu menu = new Menu(id, parentId, rs.getString(INDEX_FRM), getVersion2String(rs, INDEX_IMG),
getVersion2String(rs, INDEX_STL), getVersion2String(rs, INDEX_CLS), rs.getString(INDEX_DSP),
rs.getString(INDEX_FLG));
if (!menuList.containsKey(id))
menuList.put(id, menu);
if (!frequentList.containsKey(id))
frequentList.put(id, menu);
} else if (TYPE_VISIBLE.equals(type)) { // 可见菜单直接增加至可见,增加待删除常用
if (!menuList.containsKey(id)) {
Menu menu = new Menu(id, parentId, rs.getString(INDEX_FRM), getVersion2String(rs, INDEX_IMG),
getVersion2String(rs, INDEX_STL), getVersion2String(rs, INDEX_CLS), rs.getString(INDEX_DSP),
rs.getString(INDEX_FLG));
menuList.put(id, menu);
}
if (!_removeFrequentList.contains(id))
_removeFrequentList.add(id);
} else if (TYPE_INVISIBLE.equals(type)) { // 不可见菜单,增加待删除和待删除常用
if (!_removeMenuList.contains(id))
_removeMenuList.add(id);
if (!_removeFrequentList.contains(id))
_removeFrequentList.add(id);
}
}
if (!flag) { // 从第二条(含)角色信息开始
// 如果之前为待删除,但在本次不为待删除则剔除;常用菜单处理亦然
for (int i = removeMenuList.size() - 1; i >= 0; i--)
if (!_removeMenuList.contains(removeMenuList.get(i)))
removeMenuList.remove(i);
for (int i = removeFrequentList.size() - 1; i >= 0; i--)
if (!_removeFrequentList.contains(removeFrequentList.get(i)))
removeFrequentList.remove(i);
}
}
private boolean addMenu(MenuItem item, Menu parentMenu, Menu menu) {
if (parentMenu == null || parentMenu.id.equals(item.id)) {
item.add(new MenuItem(menu.id, getI18nValue(menu.descriptionKey), menu.transactionName, menu.image));
return true;
}
for (IMenuItem subItem : item)
if (addMenu((MenuItem) subItem, parentMenu, menu))
return true;
return false;
}
class Menu implements Comparable<Menu> {
String id;
String parentId;
String transactionName;
String image;
String style;
String styleClass;
String descriptionKey;
String flag;
public Menu(String id, String parentId, String transactionName, String image, String style, String styleClass,
String descriptionKey, String flag) {
this.id = id;
this.parentId = parentId;
this.transactionName = transactionName;
this.image = image;
this.style = style;
this.styleClass = styleClass;
this.descriptionKey = descriptionKey;
this.flag = flag;
}
@Override
public int compareTo(Menu menu) {
if (parentId == null && menu.parentId != null)
return -1;
else if (parentId != null && menu.parentId == null)
return 1;
return id.compareTo(menu.id);
}
@Override
public String toString() {
if (parentId == null)
return "<NULL>" + id + transactionName;
return parentId + id + transactionName;
}
}
class MenuItem extends MenuItemImpl {
String id;
MenuItem() {
}
MenuItem(String id, String label, String transactionName, String image) {
super(label, transactionName, image);
if (image == null && imageNull != null)
this.image = imageNull;
this.id = id;
}
@Override
public String toString() {
return String.format("Id = %s,Label = %s,Value = %s", id, label, value);
}
}
package cn.com.brilliance.eibs.auth;
import log.Log;
import log.LogFactory;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.dbutils.DbUtils;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.engine.spi.SessionImplementor;
import org.sss.common.impl.AbstractLoginContext;
import org.sss.common.impl.MenuItemImpl;
import org.sss.common.model.IContext.DataType;
import org.sss.common.model.IFilter;
import org.sss.common.model.IMenuItem;
import org.sss.module.hibernate.HibernateUtils;
import org.sss.module.pojo.DatabaseUtils;
import org.sss.presentation.noui.api.response.ErrorCode;
import org.sss.presentation.noui.util.NoUiUtils;
import org.sss.presentation.noui.util.StringUtil;
import org.sss.util.ContainerUtils;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.sql.*;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.Date;
/**
* LoginModule实现示例
*
* @author Jason.Hoo (latest modification by $Author: hujianxin $)
* @version $Revision: 922 $ $Date: 2014-11-19 16:05:38 +0800 (Wed, 19 Nov 2014)
* $
*/
public class DatabaseLoginContextForELCS extends AbstractLoginContext {
public static final String ERROR = "error";
final static Log log = LogFactory.getLog(DatabaseLoginContextForELCS.class);
final static String ERROR_USERNAME_PASSWORD = "error.username.password";
final static String ERROR_USER_LOCKED = "error.user.locked";
final static String ERROR_USER_EXPRIED = "error.user.expired";
final static String ERROR_SYSTEM_FAULT = "error.system.fault";
final static String STATUS_NORMAL = "0";
final static String STATUS_EXPIRED = "1";
final static String STATUS_LOCKED = "2";
final static String TYPE_VISIBLE = "0";
final static String TYPE_INVISIBLE = "1";
final static String TYPE_FREQUENT = "2";
final static String FLAG_NORMAL = "0";
final static String FLAG_INDIRECT = "1";
final static String FLAG_SKIP = "2";
final static String MENU_FREQUENT_ITEM = "menu.frequent";
final static int INDEX_INR = 1;
final static int INDEX_PNTINR = 2;
final static int INDEX_FRM = 3;
final static int INDEX_DSP = 4;
final static int INDEX_TYP = 5;
final static int INDEX_FLG = 6;
final static int INDEX_IMG = 7;
final static int INDEX_STL = 8;
final static int INDEX_CLS = 9;
final static String PWDERROR = "ESFEERROR1";
final static String VCODEERROR = "ESFEERROR2";
final static String REDISERROR = "ESFEERROR3";
final static String INITERROR = "ESFEERROR4";
private static final String loginCheck = "loginCheck.properties";
private static final String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALTHSCdzrBYyWReFrasVB+ehvfOg/34nTPPNSJsTlr0vqwvVohhqhnlBtIGE1g1//stMcAso8CevpCnN5/cOiwubzFhm1dRsyQmmkiMzH68sNx8+h87X/XeKpWIVSswc2Z3nMMV8zTDK8KhpPJwVRIQ5CqPdiYpQoDhBB5POiWPdAgMBAAECgYAxYCzI+cMK3P2QeyaQD9J05axoGpUt87YE8RDfql4Fljt1pAf9+zp3bAbNSWbdkRQamuoPYkMV09dWw7KTvBklwQe91llTF3eHXKXmI5M+NJtlfmk2aeJCwmb8LtFyIMb3ocgvni5es/jEd/UTzZvzZpbkR+aD5aiXEC/wFCNJUQJBANfQuCDO2d7MIfv36DKbGJ25oqX/e2B/GWDhNGb3F4BqN+3MkFw21MAP3OlW/nu0XgyRLVzw8pm6E6WlBR3GPGMCQQDWcHVWr7fIeQ9sLAKwhe+D4k/kPElaptxoqzMIWNcweG5fc2eMvJ5BHh081B0h4+KiLE6lgvitZU2c8aCm/TK/AkAuJ7U5TwPJYl7iRGKkcAcTtF/UoI8CVCxZS9CpNK8SB6VudhFpp1BYwwu7258RVcHHbkUFW4KG3gTVqDUv6PWBAkEAsuD6sMZB68Q4vkZ0M+Z2JzDI7h3wHuOkZtew6VyanT9I6uysy3SoGq/ROeXDK3samaeWL3DymkowFSRmnAYIpwJABliTTManT9rkQx+sahGwGKInAClxl3Po5XB8ST/75xkSobYAVaV8kgrxE4u4DJxbomBUWeT7oOOhX2vODMhuZg==";
public static int defaultSessionTimeout = 3600;
public static String defaultHomePageName = "/layout.zul";
public static String defaultHomeTransaction = "office";
public static boolean guestAccountUsed = false;
public static boolean loginOnlyOnce = true;
public static String imageNull = null;
public static String imageFrequent = null;
static int ERROR_MAX_COUNT = 5;
//用户距离上次修改密码间隔
private static Duration pwdAmeInterval = Duration.ofDays(30);
//连续多次输入密码重置
private static int maxfltcnt = 5;
static {
init();
}
protected final MenuItem menu = new MenuItem();
private String userId;
private String userRol;
private String userEty;
private Timestamp pwdamedat;
private String ukey;
private String homePageName = "/layout.zul";
private String homeTransaction = "office";
private int sessionTimeout = 3600;
private static void init() {
try {
Properties props = new Properties();
// 加载配置文件
props.load(DatabaseLoginContextForELCS.class.getClassLoader().getResourceAsStream(loginCheck));
pwdAmeInterval = Duration.ofDays(Integer.parseInt(props.getProperty("pwdAmeInterval")));
maxfltcnt = Integer.parseInt(props.getProperty("maxfltcnt"));
} catch (Throwable e) {
log.warn("初始化异常", e);
recordException(INITERROR, "初始化异常:" + e.getMessage(), "ERROR");
}
}
public static void recordException(String srvcod, String errormsg, String lev) {
Session session = HibernateUtils.openSession(null);
long count = DatabaseUtils.executeCounter(((SessionImplementor) session).connection(), "dealog");
String inr = String.format("%08d", count);
Transaction transaction = session.beginTransaction();
SQLQuery sqlQuery = session.createSQLQuery("insert into dealog(INR,CREDATTIM,SRVCOD,SRVNAM,INIFRM,RTNMSG,LOGLEV) values(?,?,?,?,?,?,?)");
sqlQuery.setString((Integer) 0, inr);
sqlQuery.setTimestamp(1, new Date());
sqlQuery.setString(2, srvcod);
sqlQuery.setString(3, srvcod);
sqlQuery.setString(4, "LOGIN");
sqlQuery.setString(5, errormsg);
sqlQuery.setString(6, lev);
sqlQuery.executeUpdate();
transaction.commit();
session.close();
log.debug("完成登陆相关异常日志记录");
}
/**
* 用户原文密码解密,先传统base64解密,然后对解密后的字符串的首位字符串进行偏移【头4 尾7】
*
* @param verifycode 验证码
* @param pwd 待解签串
* @return 解签后的字符串
*/
public static String pwdDecode(String verifycode, String pwd) {
if (StringUtil.isEmpty(pwd)) {
return "";
}
try {
// pwd = AESUtil.decryptAES(pwd,verifycode);
pwd = decrypt(pwd);
} catch (Throwable e) {
log.warn("密码解密异常:", e);
recordException(PWDERROR, "密码解密异常:" + e.getMessage(), "FATAL");
}
return pwd;
}
public static String decrypt(String pwd) throws Exception {
pwd = pwd.replaceAll("%2B", "+");
//64位解码加密后的字符串
byte[] inputByte = org.apache.commons.codec.binary.Base64.decodeBase64(pwd.getBytes("UTF-8"));
//base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte), "UTF-8");
return outStr;
}
//偏移 头4 尾7
private static String convert(String str) {
if (str.length() == 1) {
return change(str.charAt(0), 4);
} else if (str.length() == 2) {
return change(str.charAt(0), 4) + change(str.charAt(1), 7);
} else {
String btw_str = str.substring(1, str.length() - 1);
String head = change(str.charAt(0), 4);
String tail = change(str.charAt(str.length() - 1), 7);
return head + btw_str + tail;
}
}
//根据偏移量转换字符
private static String change(char ch, int offset) {
int before = ch;
int after;
//a-z
if (ch >= 97 && ch <= 122) {
if (before + offset <= 122) {
after = before + offset;
} else {
after = (before + offset) % 122 + 96;
}
return String.valueOf((char) after);
}
//A-Z
else if (ch >= 65 && ch <= 90) {
if (before + offset <= 90) {
after = before + offset;
} else {
after = (before + offset) % 90 + 64;
}
return String.valueOf((char) after);
}
//0-9
else if (ch >= 48 && ch <= 57) {
if (before + offset <= 57) {
after = before + offset;
} else {
after = (before + offset) % 57 + 47;
}
return String.valueOf((char) after);
}
return String.valueOf(ch);
}
protected boolean isVersion2() {
return false;
}
private String getVersion2Sql() {
return isVersion2() ? ",m.img,m.stl,m.stlcls" : "";
}
private String getVersion2String(ResultSet rs, int index) throws SQLException {
return isVersion2() ? rs.getString(index) : null;
}
private boolean setLogon(boolean flag, String userName, String type, String logText, Statement stmt, ResultSet rs) {
DbUtils.closeQuietly(rs);
DbUtils.closeQuietly(stmt);
if (flag) {
if (loginOnlyOnce)
ctx.logout(DataType.USER_NAME, userName);
this._userName = userName;
}
if (log.isDebugEnabled()) {
log.debug(String.format("%s,userName=[%s]", logText, userName));
}
errorText = flag ? "" : getI18nValue(type);
this.flag = flag;
return flag;
}
private String getI18nValue(String key) {
return ctx.getGui().getI18nValue("eibs", key);
}
private boolean setAuth(boolean flag, Statement stmt1, ResultSet rs1, Statement stmt2, ResultSet rs2) {
DbUtils.closeQuietly(rs1);
DbUtils.closeQuietly(stmt1);
DbUtils.closeQuietly(rs2);
DbUtils.closeQuietly(stmt2);
this.authed = flag;
return flag;
}
@Override
public String getHomePageName() {
return homePageName;
}
@Override
public String getHomeTransaction() {
return homeTransaction;
}
@Override
public int getSessionTimeout() {
return sessionTimeout;
}
public String checkPassword(String userName, String verifycode, String dbPassword, String password) {
password = pwdDecode(verifycode, password);
IFilter passwordFilter = NoUiUtils.passwordFilter;
if (NoUiUtils.passwordFilter == null) {
log.warn("未在eibs.xml为NoUiUtils配置passwordFilter项");
recordException(PWDERROR, "密码校验异常:未在eibs.xml为NoUiUtils配置passwordFilter项", "FATAL");
return null;
}
if (dbPassword != null) {
dbPassword = dbPassword.trim();
}
// String encodedPassword = ContainerUtils.encodeWithSalt ? passwordFilter.encode(password, userName).trim() : passwordFilter.encode(password).trim();
// log.info("password反转回来==="+password+",userName===="+userName);
String encodedPassword = passwordFilter.encode(password, userName).trim();
// log.info("password国密解析==="+encodedPassword);
if (log.isDebugEnabled()) {
log.debug("password(input/db)" + dbPassword + "\t" + encodedPassword);
}
if (!encodedPassword.equals(dbPassword))
return "[Database: NOT Match.]";
return null;
}
@Override
public boolean login(Connection conn, Map parameterMap) {
this._userName = null;
String userName = getParameter(parameterMap, "j_username");
String password = getParameter(parameterMap, "j_password");
String sendcode = getParameter(parameterMap, "j_sendcode");
String verifycode = getParameter(parameterMap, "j_verifycode");
String dncode = getParameter(parameterMap, "j_dncode");
String channel = getParameter(parameterMap, "j_channel");
if (userName == null || password == null || dncode == null) {
parameterMap.put(ERROR, ErrorCode.LOGIN_PARAMETER_CHECK);
return setLogon(false, userName, ERROR_USERNAME_PASSWORD, "用户名或密码为空.", null, null);
}
ResultSet rs = null;
PreparedStatement stmt = null;
try {
if (sendcode == null || verifycode == null || !sendcode.equalsIgnoreCase(verifycode)) {
log.info("验证码验证失败,待校验:" + sendcode + ",原始:" + verifycode);
parameterMap.put(ERROR, ErrorCode.LOGIN_VERIFYCODE_ERROR);
return setLogon(false, userName, ErrorCode.LOGIN_VERIFYCODE_ERROR.getCode(), ErrorCode.LOGIN_VERIFYCODE_ERROR.getMessage(), stmt, rs);
}
String sql = "SELECT inr,pwd,fltcnt,sta,etyextkey,usg,pwdamedat,ukey FROM usr WHERE nam=?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, userName);
rs = stmt.executeQuery();
if (!rs.next()) {
if (!guestAccountUsed) {
parameterMap.put(ERROR, ErrorCode.LOGIN_NON_USR);
return setLogon(false, userName, ERROR_USERNAME_PASSWORD, "系统无此用户.", stmt, rs);
}
userName = "guest";
homePageName = "/register.zul";
homeTransaction = "usrreg";
sessionTimeout = -1;
return setLogon(true, userName, null, "游客成功登录.", stmt, rs);
}
userId = rs.getString(1);
if (log.isDebugEnabled()) {
log.debug("userId=" + userId);
}
String dbPassword = rs.getString(2);
int faultCount = rs.getInt(3);
String userState = rs.getString(4);// 0:正常;1:注销;2:锁定
userEty = rs.getString(5);
userRol = rs.getString(6);
pwdamedat = rs.getTimestamp(7);
ukey = rs.getString(8);
DbUtils.closeQuietly(stmt);
DbUtils.closeQuietly(rs);
if (channel == null) {
String errorStr = checkPassword(userName, sendcode, dbPassword, password);
if (STATUS_LOCKED.equals(userState)) {
parameterMap.put(ERROR, ErrorCode.LOGIN_LOCK_USR);
return setLogon(false, userName, ERROR_USER_LOCKED, "用户已被锁定.", stmt, rs);
} else if (STATUS_EXPIRED.equals(userState)) {
parameterMap.put(ERROR, ErrorCode.LOGIN_EXPRIED_USR);
return setLogon(false, userName, ERROR_USER_EXPRIED, "用户已被注销.", stmt, rs);
} else if (!STATUS_NORMAL.equals(userState)) {//非0:正常;1:注销;2:锁定,不可登录,
parameterMap.put(ERROR, ErrorCode.LOGIN_STATE_ABNORMAL_ERROR);
return setLogon(false, userName, ErrorCode.LOGIN_STATE_ABNORMAL_ERROR.getCode(), ErrorCode.LOGIN_STATE_ABNORMAL_ERROR.getMessage(), stmt, rs);
} else if (!Objects.equals(ukey, dncode)) {//dn码错误
parameterMap.put(ERROR, ErrorCode.LOGIN_DN_ERROR);
return setLogon(false, userName, ErrorCode.LOGIN_DN_ERROR.getCode(), ErrorCode.LOGIN_DN_ERROR.getMessage(), stmt, rs);
} else if (Objects.nonNull(errorStr)) {
// 校验密码
sql = "UPDATE usr SET fltcnt=?,sta=?,lstfltdattim=? WHERE inr=?";
stmt = conn.prepareStatement(sql);
faultCount++;
stmt.setInt(1, faultCount);
stmt.setString(2, faultCount >= maxfltcnt ? STATUS_LOCKED : userState);
stmt.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
stmt.setString(4, userId);
stmt.execute();
conn.commit();
if (faultCount >= maxfltcnt) {
parameterMap.put(ERROR, ErrorCode.LOGIN_PWD_CHECK);
} else {
parameterMap.put(ERROR, ErrorCode.LOGIN_PWD_ERROR);
}
return setLogon(false, userName, ERROR_USERNAME_PASSWORD, String.format("密码验证失败.%s.", errorStr), stmt,
rs);
} else if (Objects.isNull(pwdamedat)) {//初次登陆
parameterMap.put(ERROR, ErrorCode.LOGIN_FIRST_LOGIN);
return setLogon(true, userName, ErrorCode.LOGIN_FIRST_LOGIN.getCode(), ErrorCode.LOGIN_FIRST_LOGIN.getMessage(), stmt, rs);
} else if (pwdamedat.toLocalDateTime().plus(pwdAmeInterval).isBefore(LocalDateTime.now())) {//超过指定时间仍为修改密码
parameterMap.put(ERROR, ErrorCode.LOGIN_PWD_AME_INTERVAL);
return setLogon(true, userName, ErrorCode.LOGIN_PWD_AME_INTERVAL.getCode(), ErrorCode.LOGIN_PWD_AME_INTERVAL.getMessage(), stmt, rs);
}
if (log.isDebugEnabled()) {
log.debug("faultCount=" + faultCount);
}
}
sql = "UPDATE usr SET fltcnt=?,sta=?,lstdattim=? WHERE inr=?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, 0);
stmt.setString(2, STATUS_NORMAL);
stmt.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
stmt.setString(4, userId);
stmt.execute();
conn.commit();
// 监控用户返回监控页面
if ("monitor".equals(userName)) {
homePageName = "/monitor.zul";
homeTransaction = "monitor";
sessionTimeout = -1;
return setLogon(true, userName, null, "监控用户成功登录.", stmt, rs);
}
homePageName = defaultHomePageName;
homeTransaction = defaultHomeTransaction;
sessionTimeout = defaultSessionTimeout;
} catch (Throwable e) {
log.error("系统登录内部错误", e);
parameterMap.put(ERROR, ErrorCode.SYSTEM_ERROR);
return setLogon(false, userName, ERROR_SYSTEM_FAULT, "系统内部错误.", stmt, rs);
}
return setLogon(true, userName, null, "成功登录.", stmt, rs);
}
@Override
public boolean auth(Connection conn, Map parameterMap) {
if (log.isDebugEnabled()) {
log.debug("正在加载当前用户菜单.");
}
String sql = "";
ResultSet rs = null;
PreparedStatement stmt = null;
ResultSet subRs = null;
PreparedStatement subStmt = null;
try {
// 进行菜单处理
Map<String, Menu> menuMap = new HashMap(); // 全部菜单
Map<String, Menu> frequentMap = new HashMap(); // 常用菜单
// 加载所有默认可访问的交易
// sql = "SELECT inr,pntinr,frm,dsp,typ,flg" + getVersion2Sql() + " FROM frm m
// WHERE typ=? OR typ=?"
sql = "select frm.inr,frm.pntinr,frm.frm,frm.dsp,frm.typ,frm.flg from frm,frr where frr.rol=? and frr.etyextkey=? and frr.frm=substr(frm.dsp,6)";
stmt = conn.prepareStatement(sql);
stmt.setString(1, userRol);
stmt.setString(2, userEty);
rs = stmt.executeQuery();
while (rs.next()) {
String id = rs.getString(INDEX_INR);
Menu menu = new Menu(id, rs.getString(INDEX_PNTINR), rs.getString(INDEX_FRM),
getVersion2String(rs, INDEX_IMG), getVersion2String(rs, INDEX_STL),
getVersion2String(rs, INDEX_CLS), rs.getString(INDEX_DSP), rs.getString(INDEX_FLG));
if (!menuMap.containsKey(id))
menuMap.put(id, menu);
if (TYPE_FREQUENT.equals(rs.getString(INDEX_TYP)))
if (!frequentMap.containsKey(id))
frequentMap.put(id, menu);
}
DbUtils.closeQuietly(stmt);
DbUtils.closeQuietly(rs);
// 进行排序
List<Menu> menus = new ArrayList(menuMap.values());
Collections.sort(menus);
List<Menu> frequents = new ArrayList(frequentMap.values());
Collections.sort(frequents);
// 通过addMenu查询并增加菜单(若未添加成功直接添加为根菜单),同时添加可访问交易
for (Menu menu : menus) {
if (!ContainerUtils.isEmpty(menu.transactionName))
this.trans.put(menu.transactionName, getI18nValue(menu.descriptionKey));
if (!FLAG_INDIRECT.equals(menu.flag) && !addMenu(this.menu, menuMap.get(menu.parentId), menu))
this.menu.add(
new MenuItem(menu.id, getI18nValue(menu.descriptionKey), menu.transactionName, menu.image));
}
// 删除菜单中为空的父项
checkMenu(this.menu);
// 添加常用菜单
MenuItem frequentItem = new MenuItem(null, getI18nValue(MENU_FREQUENT_ITEM), null, imageFrequent);
for (Menu frequent : frequents)
if (!FLAG_INDIRECT.equals(frequent.flag))
frequentItem.add(new MenuItem(frequent.id, getI18nValue(frequent.descriptionKey),
frequent.transactionName, frequent.image));
if (!frequentItem.isEmpty())
this.menu.add(frequentItem);
} catch (Exception e) {
return setAuth(false, stmt, rs, subStmt, subRs);
}
return setAuth(true, stmt, rs, subStmt, subRs);
}
public IMenuItem filterMenu(IMenuItem menuItem, String filter) {
for (IMenuItem item : menuItem) {
if (filter.equals(((MenuItem) item).id))
return item;
IMenuItem result = filterMenu(item, filter);
if (result != null)
return result;
}
return null;
}
@Override
public IMenuItem getMenu() {
if (ContainerUtils.isEmpty(menuFilter))
return menu;
return filterMenu(menu, menuFilter);
}
@Override
protected String getParameter(Map map, String key) {
if (map == null)
return null;
Object o = map.get(key);
if (o == null)
return null;
else if (o instanceof String)
return (String) o;
else if (o instanceof String[])
return ((String[]) o)[0];
else
return o.toString();
}
@Override
public Object getValue(String key) {
if ("usrinr".equals(key))
return userId;
return null;
}
@Override
public String getCustomNumber() {
return "";
}
protected void checkMenu(IMenuItem menu) {
for (int i = menu.size() - 1; i >= 0; i--) {
IMenuItem item = menu.get(i);
if (ContainerUtils.isEmpty(item.getValue())) {
if (item.isEmpty())
menu.remove(item);
else
checkMenu(item);
}
}
}
private void calculateMenu(ResultSet rs, Map<String, Menu> menuList, Map<String, Menu> frequentList,
List<String> removeMenuList, List<String> removeFrequentList, boolean flag) throws Exception { // 如果为用户信息或第一条角色信息时,直接操作待删除菜单和待删除常用菜单
// 注:多角色叠加菜单时以最大可显示的方式进行处理:可见/常用直接增加,不可见或不常用待全部角色都不可见或不常用时才处理(多角色在所有角色处理结束后再处理)
// 当flag为true时表示直接处理/直接处理待删除菜单和待删除常用菜单、false时表示需多次处理/本次不可见和不常用需要对原有待删除菜单和待删除常用菜单进行比较
List<String> _removeMenuList = flag ? removeMenuList : new ArrayList();
List<String> _removeFrequentList = flag ? removeFrequentList : new ArrayList();
while (rs.next()) {
String id = rs.getString(INDEX_INR);
String parentId = rs.getString(INDEX_PNTINR);
String type = rs.getString(INDEX_TYP);
if (TYPE_FREQUENT.equals(type)) { // 常用菜单直接增加至可见和常用
Menu menu = new Menu(id, parentId, rs.getString(INDEX_FRM), getVersion2String(rs, INDEX_IMG),
getVersion2String(rs, INDEX_STL), getVersion2String(rs, INDEX_CLS), rs.getString(INDEX_DSP),
rs.getString(INDEX_FLG));
if (!menuList.containsKey(id))
menuList.put(id, menu);
if (!frequentList.containsKey(id))
frequentList.put(id, menu);
} else if (TYPE_VISIBLE.equals(type)) { // 可见菜单直接增加至可见,增加待删除常用
if (!menuList.containsKey(id)) {
Menu menu = new Menu(id, parentId, rs.getString(INDEX_FRM), getVersion2String(rs, INDEX_IMG),
getVersion2String(rs, INDEX_STL), getVersion2String(rs, INDEX_CLS), rs.getString(INDEX_DSP),
rs.getString(INDEX_FLG));
menuList.put(id, menu);
}
if (!_removeFrequentList.contains(id))
_removeFrequentList.add(id);
} else if (TYPE_INVISIBLE.equals(type)) { // 不可见菜单,增加待删除和待删除常用
if (!_removeMenuList.contains(id))
_removeMenuList.add(id);
if (!_removeFrequentList.contains(id))
_removeFrequentList.add(id);
}
}
if (!flag) { // 从第二条(含)角色信息开始
// 如果之前为待删除,但在本次不为待删除则剔除;常用菜单处理亦然
for (int i = removeMenuList.size() - 1; i >= 0; i--)
if (!_removeMenuList.contains(removeMenuList.get(i)))
removeMenuList.remove(i);
for (int i = removeFrequentList.size() - 1; i >= 0; i--)
if (!_removeFrequentList.contains(removeFrequentList.get(i)))
removeFrequentList.remove(i);
}
}
private boolean addMenu(MenuItem item, Menu parentMenu, Menu menu) {
if (parentMenu == null || parentMenu.id.equals(item.id)) {
item.add(new MenuItem(menu.id, getI18nValue(menu.descriptionKey), menu.transactionName, menu.image));
return true;
}
for (IMenuItem subItem : item)
if (addMenu((MenuItem) subItem, parentMenu, menu))
return true;
return false;
}
class Menu implements Comparable<Menu> {
String id;
String parentId;
String transactionName;
String image;
String style;
String styleClass;
String descriptionKey;
String flag;
public Menu(String id, String parentId, String transactionName, String image, String style, String styleClass,
String descriptionKey, String flag) {
this.id = id;
this.parentId = parentId;
this.transactionName = transactionName;
this.image = image;
this.style = style;
this.styleClass = styleClass;
this.descriptionKey = descriptionKey;
this.flag = flag;
}
@Override
public int compareTo(Menu menu) {
if (parentId == null && menu.parentId != null)
return -1;
else if (parentId != null && menu.parentId == null)
return 1;
return id.compareTo(menu.id);
}
@Override
public String toString() {
if (parentId == null)
return "<NULL>" + id + transactionName;
return parentId + id + transactionName;
}
}
class MenuItem extends MenuItemImpl {
String id;
MenuItem() {
}
MenuItem(String id, String label, String transactionName, String image) {
super(label, transactionName, image);
if (image == null && imageNull != null)
this.image = imageNull;
this.id = id;
}
@Override
public String toString() {
return String.format("Id = %s,Label = %s,Value = %s", id, label, value);
}
}
}
\ No newline at end of file
package org.sss.presentation.noui.controller;
import com.google.gson.Gson;
import log.Log;
import log.LogFactory;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import org.sss.module.hibernate.HibernateUtils;
import org.sss.presentation.noui.util.DataSecurityUtil;
import org.sss.presentation.noui.util.HttpClientUtil;
import org.sss.presentation.noui.util.StringUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller
@PropertySource({"classpath:coas.properties"})
public class CoasHandleController {
final static Log log = LogFactory.getLog(CoasHandleController.class);
@Value("${client_id:ESFE}")
private String client_id;
@Value("${client_secret}")
private String client_secret;
@Value("${coas_server}")
private String coas_server;
private Gson gson = new Gson();
@RequestMapping(value = "/oaut2/callback", method = {RequestMethod.POST, RequestMethod.GET})
public ModelAndView callback(@RequestParam("type") String type, @RequestParam("value") String value, @RequestHeader(value = "certdn", required = false) String certdn, ModelAndView view) {
try {
Map<String, String> body = new HashMap<>();
body.put("client_id", client_id);
body.put("client_secret", client_secret);
body.put("code", value);
String url = coas_server + "get_token?client_id={client_id}&client_secret={client_secret}&code={code}";
if (!StringUtil.isEmpty(certdn)) {
body.put("user_certdn", certdn);
url += "&user_certdn={user_certdn}";
}
log.info("准备请求:" + url + "请求参数:" + body);
// ResponseEntity<String> res = HttpClientUtil.post(coas_server + "get_token", body, String.class);
ResponseEntity<String> res = HttpClientUtil.post(url, null, String.class, body);
String res_str = res.getBody();
Map<String, Object> res_body = gson.fromJson(res_str, Map.class);
log.info("调用coas的get_token接口响应:" + res_body);
checkRes(res, (String) res_body.get("msgCode"), (String) res_body.get("message"), "get_token");
String access_token = (String) res_body.get("access_token");
String token_type = (String) res_body.get("token_type");
// log.info(String.format("准备调用coas的get_info接口.access_token=[%s],token_type=[%s]", access_token, token_type));
body = new HashMap<>();
body.put("access_token", access_token);
// res = HttpClientUtil.post(coas_server + "get_info", body, String.class);
url = coas_server + "get_info?access_token={access_token}";
log.info("准备请求:" + url + "请求参数:" + body);
res = HttpClientUtil.post(url, null, String.class, body);
res_str = res.getBody();
res_body = gson.fromJson(res_str, Map.class);
log.info("调用coas的get_info接口响应:" + res_body);
checkRes(res, (String) res_body.get("msgCode"), (String) res_body.get("message"), "get_info");
Map<String, Object> info = (Map<String, Object>) res_body.get("info");
log.info("获取到用户信息:" + info);
String userid = (String) info.get("loginid");
//验证该用户是否在我方存在
Session session = HibernateUtils.openSession(null);
SQLQuery sqlQuery = session.createSQLQuery("SELECT inr FROM usr WHERE nam='" + userid + "'");
List list = sqlQuery.list();
session.close();
if (list.size() == 0) {
//我方没有当前用户
log.error("单点登陆失败,电证前置系统没有该用户:" + userid);
view.setView(new RedirectView("/esfe/#/login?channel=coas&errtyp=L6665", false));
return view;
}
//动态生成安全盐z
String[] pars = {userid};
String enc = DataSecurityUtil.encrypt(pars, userid);
//准备调我方主交易
StringBuilder sb = new StringBuilder("/esfe/#/login?channel=coas&userId=");
sb.append(userid);
sb.append("&enc=");
sb.append(enc);
view.setView(new RedirectView(sb.toString(), false));
return view;
} catch (Exception e) {
//失败后默认进入我方登陆页面,并给出错误信息
if (e instanceof CoasInfCallException) {
String errtyp = ((CoasInfCallException) e).getErrorCode();
view.setView(new RedirectView("/esfe/#/login?channel=coas&errtyp=" + errtyp, false));
} else {
log.error(e.getMessage(), e);
view.setView(new RedirectView("/esfe/#/login?channel=coas&errtyp=L6666", false));
}
return view;
}
}
/**
* 模拟coas得get_token接口
*
* @return
*/
@ResponseBody
@RequestMapping(value = "/oaut2/get_token", method = RequestMethod.POST)
public Object getToken() {
Map<String, String> res = new HashMap<>();
res.put("msgCode", "0000");
res.put("message", "success");
res.put("token_type", "jwt");
res.put("expires_in", "3600");
res.put("access_token", "PExDSWQ+CiAgICAgICAgICAgICAgICA8SXNzQmtDZD4xMDIxMDAwOTk5OTY8L0lzc0JrQ2Q+CiAgICAgICAgICAgICAgICA8TENOYj4yMDE5MDczMTAwMzAwMDAxPC9MQ05iPgogICAgICAgICAgICA8L0xDSWQ+CiAgICAgICAgICAgIDxQcmVzbklkPgogICAgICAgICAgICAgICAgPFByZXNuQmtDb2RlPjEwNTEwMDAwMDAxNzwvUHJlc25Ca0NvZGU+CiAgICAgICAgICAgICAgICA8UHJlc25OYj4xMjM0NTY3ODkxMjM0NTY3ODkxMjwvUHJlc25OYj4KICAgICAgICAgICAgPC9QcmVzbklkPg==");
return res;
}
/**
* 模拟coas得get_token接口
*
* @return
*/
@ResponseBody
@RequestMapping(value = "/oaut2/get_info", method = RequestMethod.POST)
public Object getInfo() {
Map<String, Object> res = new HashMap<>();
res.put("msgCode", "0000");
res.put("message", "success");
Map<String, String> info = new HashMap<>();
info.put("loginid", "system02");
info.put("uname", "共享前置管理员");
res.put("info", info);
return res;
}
private void checkRes(ResponseEntity<String> res, String code, String msg, String inf) {
int status = res.getStatusCodeValue();
if (200 == status) {
if (!"0000".equals(code)) {
log.error("调用" + inf + "接口失败:" + code + ",具体处理信息:" + msg);
throw new CoasInfCallException(code);
}
} else {
throw new IllegalStateException("单点登陆失败,调用coas接口失败,http返回的状态码:" + status);
}
}
class CoasInfCallException extends RuntimeException {
private String errorCode;
public CoasInfCallException(String errorCode) {
super(errorCode);
this.errorCode = errorCode;
}
public String getErrorCode() {
return errorCode;
}
}
}
......@@ -40,34 +40,50 @@ public class LoginController {
@ResponseBody
@RequestMapping(value = "/login", method = RequestMethod.POST)
public Object login(@RequestBody Map<String, Object> dataMap, HttpServletRequest request, HttpSession session) {
NoUiContext context=null;
NoUiContext context = null;
try {
NoUiRequest noUiRequest = new NoUiRequest(request, "", dataMap);
TxInfo.putTxInfo("login","/login","login");
TxInfo.putTxInfo("login", "/login", "login");
Map<String, Object> map = new HashMap<>();//此map会存储返回错误码
String userId = noUiRequest.getDataMap().get(Constants.USERNAME).toString();
String password = noUiRequest.getDataMap().get(Constants.PASSWORD).toString();
String dncode = noUiRequest.getDataMap().get(Constants.DNCODE) == null ? null : noUiRequest.getDataMap().get(Constants.DNCODE).toString();
String sendcode = noUiRequest.getDataMap().get(Constants.SENDCODE) == null ? null : noUiRequest.getDataMap().get(Constants.SENDCODE).toString();
String channel = noUiRequest.getDataMap().get("channel") == null ? null : noUiRequest.getDataMap().get("channel").toString();
if (channel != null && "coas".equals(channel)) {
//coas单点登陆逻辑
//验证enc合法性
String[] pars = {userId};
String errmsg = DataSecurityUtil.checkIllegalData(password, pars, userId);
if (errmsg != null) {
return ResultUtil.result("L6664", errmsg, null, noUiVersion.getVersion());
}
map.put("j_username", userId);
map.put("j_password", password);
map.put("j_dncode", channel);
map.put("j_sendcode", channel);
map.put("j_verifycode", channel);
map.put("j_channel", channel);
} else {
//常规登陆逻辑
String dncode = noUiRequest.getDataMap().get(Constants.DNCODE) == null ? null : noUiRequest.getDataMap().get(Constants.DNCODE).toString();
String sendcode = noUiRequest.getDataMap().get(Constants.SENDCODE) == null ? null : noUiRequest.getDataMap().get(Constants.SENDCODE).toString();
// String verifycode = request.getSession().getAttribute(Constants.VERIFYCODE)==null?null:request.getSession().getAttribute(Constants.VERIFYCODE).toString();
StringBuilder key=new StringBuilder(sendcode);
if(!StringUtil.isEmpty(request.getRemoteAddr())){
key.append(request.getRemoteAddr());
StringBuilder key = new StringBuilder(sendcode);
if (!StringUtil.isEmpty(request.getRemoteAddr())) {
key.append(request.getRemoteAddr());
}
String kb = key.toString().toLowerCase();
log.info("key===" + kb);
Object verifycodeobj = RedisUtil.get(kb);
String verifycode = verifycodeobj == null ? null : verifycodeobj.toString();
map.put("j_username", userId);
map.put("j_password", password);
map.put("j_dncode", dncode);
map.put("j_sendcode", sendcode);
map.put("j_verifycode", verifycode);
RedisUtil.delete(kb);
}
String kb=key.toString().toLowerCase();
log.info("key==="+kb);
Object verifycodeobj = RedisUtil.get(kb);
String verifycode = verifycodeobj == null ? null : verifycodeobj.toString();
map.put("j_username", userId);
map.put("j_password", password);
map.put("j_dncode", dncode);
map.put("j_sendcode", sendcode);
map.put("j_verifycode", verifycode);
RedisUtil.delete(kb);
context = NoUiContextManager.createNoUiContext(noUiRequest);
if (context.getSession().login(map)) {
JwtLogin login = new JwtLogin();
login.setUserId(userId);
login.setPassword(password);
......@@ -92,17 +108,17 @@ public class LoginController {
context.getSession().chain(true, "office");
byte[] sysmodBytes = NoUiPresentationUtil.sysmodToBytes(context);
// redis中存储用户相关信息
IDatafield inridf = (IDatafield)context.getSession().getBaseObject(context.getRoot(),"sysmod\\usr\\inr");
IDatafield inridf = (IDatafield) context.getSession().getBaseObject(context.getRoot(), "sysmod\\usr\\inr");
RedisLoginInfo redisLoginInfo = new RedisLoginInfo(userId, token, NumericUtil.sessionTimeOut(), sysmodBytes, noUiRequest.getTerminalType());
redisLoginInfo.setUserInr((String)inridf.getValue()); //设置当前用户主键
redisLoginInfo.setUserInr((String) inridf.getValue()); //设置当前用户主键
request.getSession().setAttribute("token",token);
request.getSession().setAttribute("token", token);
NoUiUtils.logout(userId,"*"); //清理可能存在的历史缓存
NoUiUtils.logout(userId, "*"); //清理可能存在的历史缓存
RedisUtil.set(StringUtil.userUniqueId(noUiRequest), redisLoginInfo);
RedisUtil.set(StringUtil.getCacheSessionId(noUiRequest.getUserId()),request.getSession().getId());
RedisUtil.set(StringUtil.getCacheSessionId(noUiRequest.getUserId()), request.getSession().getId());
//解决初次登陆,超期限登陆
final Object o = map.get(ERROR);
......@@ -165,13 +181,12 @@ public class LoginController {
try {
request.getSession().removeAttribute("token");
NoUiRequest noUiRequest = new NoUiRequest(request, "", null);
NoUiUtils.logout(noUiRequest.getUserId(),"*"); //清理可能存在的历史缓存
return ResultUtil.result(ErrorCodes.SUCCESS,"退出成功",null);
}catch (Exception e)
{
NoUiUtils.logout(noUiRequest.getUserId(), "*"); //清理可能存在的历史缓存
return ResultUtil.result(ErrorCodes.SUCCESS, "退出成功", null);
} catch (Exception e) {
}
return ResultUtil.result(ErrorCodes.ERROR,"退出失败",null);
return ResultUtil.result(ErrorCodes.ERROR, "退出失败", null);
}
}
package org.sss.presentation.noui.util;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.util.Map;
public class HttpClientUtil {
static RestTemplate restTemplate;
static {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(15000);
factory.setReadTimeout(30000);
restTemplate = new RestTemplate(factory);
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
}
/**
* GET请求调用方式
*
* @param url 请求URL
* @param responseType 返回对象类型
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> get(String url, Class<T> responseType) throws RestClientException {
return restTemplate.getForEntity(url, responseType);
}
/**
* GET请求调用方式
*
* @param url 请求URL
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> get(String url, Class<T> responseType, Object... uriVariables)
throws RestClientException {
return restTemplate.getForEntity(url, responseType, uriVariables);
}
/**
* GET请求调用方式
*
* @param url 请求URL
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> get(String url, Class<T> responseType, Map<String, ?> uriVariables)
throws RestClientException {
return restTemplate.getForEntity(url, responseType, uriVariables);
}
/**
* 带请求头的GET请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> get(String url, Map<String, String> headers, Class<T> responseType,
Object... uriVariables) throws RestClientException {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return get(url, httpHeaders, responseType, uriVariables);
}
/**
* 带请求头的GET请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> get(String url, HttpHeaders headers, Class<T> responseType, Object... uriVariables)
throws RestClientException {
HttpEntity<?> requestEntity = new HttpEntity<>(headers);
return exchange(url, HttpMethod.GET, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的GET请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> get(String url, Map<String, String> headers, Class<T> responseType,
Map<String, ?> uriVariables) throws RestClientException {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return get(url, httpHeaders, responseType, uriVariables);
}
/**
* 带请求头的GET请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> get(String url, HttpHeaders headers, Class<T> responseType,
Map<String, ?> uriVariables) throws RestClientException {
HttpEntity<?> requestEntity = new HttpEntity<>(headers);
return exchange(url, HttpMethod.GET, requestEntity, responseType, uriVariables);
}
// ----------------------------------POST-------------------------------------------------------
/**
* POST请求调用方式
*
* @param url 请求URL
* @param responseType 返回对象类型
* @return
*/
public static <T> ResponseEntity<T> post(String url, Class<T> responseType) throws RestClientException {
return restTemplate.postForEntity(url, HttpEntity.EMPTY, responseType);
}
/**
* POST请求调用方式
*
* @param url 请求URL
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType)
throws RestClientException {
return restTemplate.postForEntity(url, requestBody, responseType);
}
/**
* POST请求调用方式
*
* @param url 请求URL
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType, Object... uriVariables)
throws RestClientException {
return restTemplate.postForEntity(url, requestBody, responseType, uriVariables);
}
/**
* POST请求调用方式
*
* @param url 请求URL
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType,
Map<String, ?> uriVariables) throws RestClientException {
return restTemplate.postForEntity(url, requestBody, responseType, uriVariables);
}
/**
* 带请求头的POST请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, Map<String, String> headers, Object requestBody,
Class<T> responseType, Object... uriVariables) throws RestClientException {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return post(url, httpHeaders, requestBody, responseType, uriVariables);
}
/**
* 带请求头的POST请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, HttpHeaders headers, Object requestBody, Class<T> responseType,
Object... uriVariables) throws RestClientException {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
return post(url, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的POST请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, Map<String, String> headers, Object requestBody,
Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return post(url, httpHeaders, requestBody, responseType, uriVariables);
}
/**
* 带请求头的POST请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, HttpHeaders headers, Object requestBody, Class<T> responseType,
Map<String, ?> uriVariables) throws RestClientException {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
return post(url, requestEntity, responseType, uriVariables);
}
/**
* 自定义请求头和请求体的POST请求调用方式
*
* @param url 请求URL
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, HttpEntity<?> requestEntity, Class<T> responseType,
Object... uriVariables) throws RestClientException {
return restTemplate.exchange(url, HttpMethod.POST, requestEntity, responseType, uriVariables);
}
/**
* 自定义请求头和请求体的POST请求调用方式
*
* @param url 请求URL
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, HttpEntity<?> requestEntity, Class<T> responseType,
Map<String, ?> uriVariables) throws RestClientException {
return restTemplate.exchange(url, HttpMethod.POST, requestEntity, responseType, uriVariables);
}
// ----------------------------------PUT-------------------------------------------------------
/**
* PUT请求调用方式
*
* @param url 请求URL
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, Class<T> responseType, Object... uriVariables)
throws RestClientException {
return put(url, HttpEntity.EMPTY, responseType, uriVariables);
}
/**
* PUT请求调用方式
*
* @param url 请求URL
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, Object requestBody, Class<T> responseType, Object... uriVariables)
throws RestClientException {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
return put(url, requestEntity, responseType, uriVariables);
}
/**
* PUT请求调用方式
*
* @param url 请求URL
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables)
throws RestClientException {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
return put(url, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的PUT请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, Map<String, String> headers, Object requestBody, Class<T> responseType,
Object... uriVariables) throws RestClientException {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return put(url, httpHeaders, requestBody, responseType, uriVariables);
}
/**
* 带请求头的PUT请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, HttpHeaders headers, Object requestBody, Class<T> responseType,
Object... uriVariables) throws RestClientException {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
return put(url, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的PUT请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, Map<String, String> headers, Object requestBody, Class<T> responseType,
Map<String, ?> uriVariables) throws RestClientException {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return put(url, httpHeaders, requestBody, responseType, uriVariables);
}
/**
* 带请求头的PUT请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, HttpHeaders headers, Object requestBody, Class<T> responseType,
Map<String, ?> uriVariables) throws RestClientException {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
return put(url, requestEntity, responseType, uriVariables);
}
/**
* 自定义请求头和请求体的PUT请求调用方式
*
* @param url 请求URL
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, HttpEntity<?> requestEntity, Class<T> responseType,
Object... uriVariables) throws RestClientException {
return restTemplate.exchange(url, HttpMethod.PUT, requestEntity, responseType, uriVariables);
}
/**
* 自定义请求头和请求体的PUT请求调用方式
*
* @param url 请求URL
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, HttpEntity<?> requestEntity, Class<T> responseType,
Map<String, ?> uriVariables) throws RestClientException {
return restTemplate.exchange(url, HttpMethod.PUT, requestEntity, responseType, uriVariables);
}
// ----------------------------------DELETE-------------------------------------------------------
/**
* DELETE请求调用方式
*
* @param url 请求URL
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Class<T> responseType, Object... uriVariables)
throws RestClientException {
return delete(url, HttpEntity.EMPTY, responseType, uriVariables);
}
/**
* DELETE请求调用方式
*
* @param url 请求URL
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Class<T> responseType, Map<String, ?> uriVariables)
throws RestClientException {
return delete(url, HttpEntity.EMPTY, responseType, uriVariables);
}
/**
* DELETE请求调用方式
*
* @param url 请求URL
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Object requestBody, Class<T> responseType, Object... uriVariables)
throws RestClientException {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
return delete(url, requestEntity, responseType, uriVariables);
}
/**
* DELETE请求调用方式
*
* @param url 请求URL
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Object requestBody, Class<T> responseType,
Map<String, ?> uriVariables) throws RestClientException {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
return delete(url, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Map<String, String> headers, Class<T> responseType,
Object... uriVariables) throws RestClientException {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return delete(url, httpHeaders, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Class<T> responseType, Object... uriVariables)
throws RestClientException {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(headers);
return delete(url, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Map<String, String> headers, Class<T> responseType,
Map<String, ?> uriVariables) throws RestClientException {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return delete(url, httpHeaders, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Class<T> responseType,
Map<String, ?> uriVariables) throws RestClientException {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(headers);
return delete(url, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Map<String, String> headers, Object requestBody,
Class<T> responseType, Object... uriVariables) throws RestClientException {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return delete(url, httpHeaders, requestBody, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Object requestBody, Class<T> responseType,
Object... uriVariables) throws RestClientException {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
return delete(url, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Map<String, String> headers, Object requestBody,
Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return delete(url, httpHeaders, requestBody, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Object requestBody, Class<T> responseType,
Map<String, ?> uriVariables) throws RestClientException {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
return delete(url, requestEntity, responseType, uriVariables);
}
/**
* 自定义请求头和请求体的DELETE请求调用方式
*
* @param url 请求URL
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, HttpEntity<?> requestEntity, Class<T> responseType,
Object... uriVariables) throws RestClientException {
return restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, responseType, uriVariables);
}
/**
* 自定义请求头和请求体的DELETE请求调用方式
*
* @param url 请求URL
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, HttpEntity<?> requestEntity, Class<T> responseType,
Map<String, ?> uriVariables) throws RestClientException {
return restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, responseType, uriVariables);
}
// ----------------------------------通用方法-------------------------------------------------------
/**
* 通用调用方式
*
* @param url 请求URL
* @param method 请求方法类型
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
Class<T> responseType, Object... uriVariables) throws RestClientException {
return restTemplate.exchange(url, method, requestEntity, responseType, uriVariables);
}
/**
* 通用调用方式
*
* @param url 请求URL
* @param method 请求方法类型
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity,
Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
return restTemplate.exchange(url, method, requestEntity, responseType, uriVariables);
}
}
client_id=ESFE
client_secret=666666
coas_server=http://111.1.12.211:8088/coas/oauth2/
\ No newline at end of file
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<mvc:annotation-driven>
<mvc:message-converters>
<ref bean="stringHttpMessageConverter"/>
<ref bean="mappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="stringHttpMessageConverter"
class="org.springframework.http.converter.StringHttpMessageConverter"/>
<!--解决IE浏览器json文件下载和json数据中午乱码的问题-->
<bean id="mappingJackson2HttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="200000" />
<property name="maxInMemorySize" value="200000" />
</bean>
<bean id="nouiVersion" class="org.sss.presentation.noui.api.response.NoUiVersion">
<property name="version" value="202009091600" />
<property name="rootFilePath" value="" />
</bean>
<mvc:default-servlet-handler />
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**/*" />
<bean class="org.sss.presentation.noui.filter.Cors" />
</mvc:interceptor>
<mvc:interceptor>
<!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->
<mvc:mapping path="/**" />
<!--login 不需要拦截 -->
<mvc:exclude-mapping path="/login" />
<mvc:exclude-mapping path="/getUserByDn" />
<mvc:exclude-mapping path="/login/**" />
<!--<mvc:exclude-mapping path="/fileBrowser/**" />-->
<bean class="org.sss.presentation.noui.jwt.TokenInterceptor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="org.sss.presentation.noui.filter.FileTypeInterceptor">
<property name="type_list" value="bat,sh,js,sql,exe" />
</bean>
</mvc:interceptor>
</mvc:interceptors>
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="org.sss.presentation.noui.controller"></context:component-scan>
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<mvc:annotation-driven>
<mvc:message-converters>
<ref bean="stringHttpMessageConverter"/>
<ref bean="mappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="stringHttpMessageConverter"
class="org.springframework.http.converter.StringHttpMessageConverter"/>
<!--解决IE浏览器json文件下载和json数据中午乱码的问题-->
<bean id="mappingJackson2HttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="200000" />
<property name="maxInMemorySize" value="200000" />
</bean>
<bean id="nouiVersion" class="org.sss.presentation.noui.api.response.NoUiVersion">
<property name="version" value="202009091600" />
<property name="rootFilePath" value="" />
</bean>
<mvc:default-servlet-handler />
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**/*" />
<bean class="org.sss.presentation.noui.filter.Cors" />
</mvc:interceptor>
<mvc:interceptor>
<!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->
<mvc:mapping path="/**" />
<!--login 不需要拦截 -->
<mvc:exclude-mapping path="/login" />
<mvc:exclude-mapping path="/getUserByDn" />
<mvc:exclude-mapping path="/login/**" />
<mvc:exclude-mapping path="/oaut2/**" />
<!--<mvc:exclude-mapping path="/fileBrowser/**" />-->
<bean class="org.sss.presentation.noui.jwt.TokenInterceptor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="org.sss.presentation.noui.filter.FileTypeInterceptor">
<property name="type_list" value="bat,sh,js,sql,exe" />
</bean>
</mvc:interceptor>
</mvc:interceptors>
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="org.sss.presentation.noui.controller"></context:component-scan>
</beans>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment