维柴铸造 统一门户登录

维柴项目上线 需要用户在统一门户进行用户登录,所以需开放外部登录接口
1 applicationContext-security.xml 中添加对外接口
<s:http pattern=“/**/autoLoginController2!.” security=“none” />
<s:http pattern=“.*/controller!operate.action?.bean=autoLoginController2.” security=“none” request-matcher=“regex”/>
2 代码实现
package com.epichust.mestar.management.controller;

import com.epichust.mestar.account.service.impl.UserDetailsServiceImpl;
import com.epichust.mestar.logging.MestarLogger;
import com.epichust.mestar.platform.controller.web.DefaultController;
import com.epichust.mestar.utils.exception.MestarException;
import com.epichust.mestar.utils.path.EnvUtil;
import com.epichust.mestar.utils.security.Crypt;
import com.epichust.mestar.utils.security.MD5Util;
import com.epichust.mestar.utils.spring.SpringSecurityUtils;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import java.io.IOException;
import java.io.PrintStream;
import java.net.URLEncoder;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;

@Scope(“prototype”)
@Controller
public class AutoLoginController2 extends DefaultController {
private static final String URLKEY_USERNAME = “_u”;
private static final String URLKEY_PASSWORD = “_p”;
private static final String URLKEY_TIME = “_t”;
private static final String URLKEY_PASSTYPE = “_pt”;
private static final String URLKEY_TOPAGE = “_to”;
private static final String PSW_TYPE_DEF = “crypt”;
private static final String PSW_TYPE_MD5 = “md5”;
private static final String PSW_TYPE_MIN = “min”;
private static final Long ENCRYPT_NUMBER = Long.valueOf(1800000L);
private static Long intervalTime;

/** 统一身份认证常量 **/
// 常量
//private static String COOKIE_NAME = "BBCloudBAMSession";
//private static String APP_ID = "MESCF"; // 由统一用户认证系统提供
//private static String APP_KEY = "MESCFpass"; // 由统一用户认证系统提供
//private static String REDIRECT_URL = "http://10.0.11.214:7002/apphub-webui/login"; // 统一登陆入口登陆地址

//private static String AM_REST_IS_TOKEN_VALID = "http://bimbam.bim.com:7003/bam/identity/json/isTokenValid?tokenid=";// 验证token是否有效地址
//private static String AM_REST_ATTR = "http://bimbam.bim.com:7003/bam/identity/json/attributesapi?tokenid=";

//private static String REDIRECT_URL = "http://daohangtest.weichai.com:7002/apphub-webui/login"; //统一登陆入口登陆地址

//private static String AM_REST_IS_TOKEN_VALID = "bamtest.weichai.com:7003/bam/identity/json/isTokenValid?tokenid=";//验证token是否有效地址
//private static String AM_REST_ATTR = "http://bamtest.weichai.com:7003/bam/identity/json/attributesapi?tokenid=";

private static String APP_ID = "MESCF"; //由统一用户认证系统提供

private static String APP_KEY = " MESCFpass "; //由统一用户认证系统提供

private static String COOKIE_NAME = "BBCloudBAMSession";

private static String REDIRECT_URL = "http://daohang.weichai.com";

private static String AM_REST_IS_TOKEN_VALID = "http://bam.weichai.com:7011/bam/identity/json/isTokenValid?tokenid=";

private static String AM_REST_ATTR ="http://bam.weichai.com:7011/bam/identity/json/attributesapi?tokenid=";

/************************/

@Autowired
private UserDetailsServiceImpl userDetailService;

// 统一身份 维柴提供,参考sso.jsp
private static String getText(String httpUrl) {
	String getText = "";
	HttpURLConnection connection = null;
	try {
		URL url = new URL(httpUrl);
		connection = (HttpURLConnection) url.openConnection();
		connection.setDoOutput(true);
		connection.setRequestMethod("GET");
		connection.connect();
		int rsp = connection.getResponseCode();
		if (rsp == HttpURLConnection.HTTP_OK) {
			BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
			String inputLine;
			while ((inputLine = in.readLine()) != null) {
				getText = getText + inputLine;
			}
			in.close();
		} else if (rsp == HttpURLConnection.HTTP_UNAUTHORIZED) {
			BufferedReader in = new BufferedReader(new InputStreamReader(connection.getErrorStream(), "UTF-8"));
			String inputLine;
			while ((inputLine = in.readLine()) != null) {
				getText = getText + inputLine;
			}
			in.close();
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		if (connection != null) {
			connection.disconnect();
		}
	}
	return getText;
}

private JSONArray getJsonArray(JSONObject jsonObject) {
	return jsonObject.getJSONArray("attributes").getJSONObject(0).getJSONArray("values");
}

private static String getTokenFromCookie(HttpServletRequest request) {
	String cookieToken = null;
	javax.servlet.http.Cookie[] cookies = request.getCookies();
	if (cookies != null) {
		for (Cookie cookie : cookies) {
			if (COOKIE_NAME.equalsIgnoreCase(cookie.getName())) {
				if (!"".equalsIgnoreCase(cookie.getValue())) {
					cookieToken = cookie.getValue();
				}
			}
		}
	}
	return cookieToken;
}

public void login() {

	HttpServletResponse response = this.pageData.getResponse();
	HttpServletRequest request = this.pageData.getRequest();

	MestarLogger.debug("------=-=-=-=-=-=--=-=-=-=-=-=-");
	MestarLogger.debug("------  Auto Login  -=-=-=-=-=-");
	MestarLogger.debug("------   统一身份认证         -=-=-=-=-=-");
	MestarLogger.debug("------=-=-=-=-=-=--=-=-=-=-=-=-");
	Map params = this.pageData.getParams();
	// 登录名称
	String userName =null;// (String) params.get("_u");
	/**
	if(1==1)
	{
		login2(userName);
		
		
		response.addHeader("P3P", "CP=CAO PSA OUR");
		try {
			//进入系统导航栏
			//response.sendRedirect("index-desktop.jsp");
			
			response.sendRedirect("index.jsp");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	**/
	/*
	 * SecurityContextImpl sscontext = this.pageData.getRequest().getSession()
	 * .getAttribute("SPRING_SECURITY_CONTEXT") == null ? null :
	 * (SecurityContextImpl) this.pageData.getRequest().getSession()
	 * .getAttribute("SPRING_SECURITY_CONTEXT");
	 */

	/************ 集成统一身份认证信息 start *****************/

	// 逃生通道配置,需要各应用系统自己设置一个参数用来控制逃生通道的开启和关闭
	// 后期行方要求各应用系统走逃生通道的时候,会通过各种方式通知到各应用的运维管理员,运维管理员手动更改此参数进行逃生通道的开启
	// 例如:在配置文件中这只一个参数,该参数的值为1时开启逃生通道,获取的参数值result==1的时候,进入逃生通道
	
	
	/*
	 * String result="2"; //后期改为配置文件读取 if (result == "1") {
	 * System.out.println("######进入应急通道######"); // 应该跳转到各个应用系统的逃生通道,依据系统自身的登陆页面认证。
	 * }
	 */
	
	
	
	String accountName = "";
	String token = "";
	JSONObject jsonObjectValid;
	JSONObject jsonObjectAccount;
	Boolean isValid = false;
	String requesttoken = request.getParameter(COOKIE_NAME);
	if (requesttoken != null && !requesttoken.equals("")) {
		System.out.println("----requesttoken is: " + requesttoken + "-------------");
		token = requesttoken;
	} else {
		String cookieToken = getTokenFromCookie(request);
		System.out.println("-----cookietoken is: " + cookieToken + "-------------");
		token = cookieToken;
	}
	if (token != null && !token.equals("")) {
		String isTokenValidUrl = AM_REST_IS_TOKEN_VALID + token;
		String verifyData = getText(isTokenValidUrl);
		jsonObjectValid = JSONObject.fromObject(verifyData);
		System.out.println("----------------jsonObject is:" + jsonObjectValid + "---------------");
		if (jsonObjectValid.has("boolean")) {
			if (jsonObjectValid.getBoolean("boolean")) {
				isValid = true;
			}
			System.out.println("----------------isValid is:" + isValid + "--------------");
		}
		if (isValid) {
			String getAttrUrl = AM_REST_ATTR + token + "&attributenames=accountName&app_id=" + APP_ID + "&app_key="
					+ APP_KEY;
			String attrData = getText(getAttrUrl);
			jsonObjectAccount = JSONObject.fromObject(attrData);
			if (jsonObjectAccount.getJSONArray("attributes").isArray()) {
				JSONArray accountJsonArray = getJsonArray(jsonObjectAccount);
				accountName = accountJsonArray.getString(0);
				// 这里的得到的是应用系统的账号,后续认证逻辑应用系统自身完成,一般的处理方法是根据账号去数据库中查,
				// 若存在进入应用系统index界面,若不存在抛出异常。(依据各个应用系统的认证逻辑而定,这里只提供参考)
		
				// 已经通过维柴系统登录系统验证,不在验证本系统密码
				userName=accountName;
				//用户登录
				login2(userName);
				
				
				response.addHeader("P3P", "CP=CAO PSA OUR");
				try {
					//进入系统导航栏
					response.sendRedirect("index-desktop.jsp");
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} else {
			try {
				response.sendRedirect(REDIRECT_URL);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	} else {
		try {
			response.sendRedirect(REDIRECT_URL);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/************* 集成统一身份认证信息 end *******************/
	
	
}

private void login2(String userName) {
	UserDetails udetails = this.userDetailService.loadUserByUsername(userName);

	SecurityContextHolder.setContext(new SecurityContextImpl());
	SpringSecurityUtils.saveUserDetailsToContext(udetails, this.pageData.getRequest());
	this.pageData.getRequest().getSession().setAttribute("SPRING_SECURITY_CONTEXT",
			SecurityContextHolder.getContext());
	this.pageData.getRequest().getSession().setAttribute("CURRENT_USER_NAME", userName);
}

/**
 * public void login() { MestarLogger.debug("------=-=-=-=-=-=--=-=-=-=-=-=-");
 * MestarLogger.debug("------ Auto Login -=-=-=-=-=-");
 * MestarLogger.debug("------ 自动登陆 -=-=-=-=-=-");
 * MestarLogger.debug("------=-=-=-=-=-=--=-=-=-=-=-=-"); Map params =
 * this.pageData.getParams(); String userName = (String) params.get("_u");
 * String password = (String) params.get("_p"); String passtype = (String)
 * params.get("_pt"); String time = (String) params.get("_t");
 * //替换跳转地址为平台登录后访问首页 params.put("_too", "index.action");
 * 
 * SecurityContextImpl sscontext =
 * this.pageData.getRequest().getSession().getAttribute("SPRING_SECURITY_CONTEXT")
 * == null ? null : (SecurityContextImpl)
 * this.pageData.getRequest().getSession().getAttribute("SPRING_SECURITY_CONTEXT");
 * 
 * if ((com.epichust.mestar.utils.lang.StringUtils.isEmpty(password)) &&
 * (com.epichust.mestar.utils.lang.StringUtils.isNotEmpty(time))) { if
 * (org.apache.commons.lang.StringUtils.isNumeric(time)) { Long timeLong =
 * Long.valueOf(Long.parseLong(time) + ENCRYPT_NUMBER.longValue()); Long nowTime
 * = Long.valueOf(System.currentTimeMillis()); if (Math.abs(nowTime.longValue()
 * - timeLong.longValue()) <= intervalTime.longValue()) { if (sscontext != null)
 * { String sname = sscontext.getAuthentication().getName();
 * 
 * if (!sname.equals(userName)) { login(userName); } } else { login(userName); }
 * } } } else { String md5psw = processPassword(password, passtype); if
 * (sscontext != null) { String sname = sscontext.getAuthentication().getName();
 * 
 * if (!sname.equals(userName)) { login(userName, md5psw); } else { Object
 * creObj = sscontext.getAuthentication().getCredentials(); if ((creObj == null)
 * || (!creObj.toString().equals(md5psw))) { login(userName, md5psw); } } } else
 * { login(userName, md5psw); }
 * 
 * }
 * 
 * redirect2Page(params); }
 **/
private void login(String userName, String password) {
	UserDetails udetails = this.userDetailService.loadUserByUsername(userName);

	if ((udetails != null) && (udetails.getPassword().equals(password))) {
		SecurityContextHolder.setContext(new SecurityContextImpl());
		SpringSecurityUtils.saveUserDetailsToContext(udetails, this.pageData.getRequest());
		this.pageData.getRequest().getSession().setAttribute("SPRING_SECURITY_CONTEXT",
				SecurityContextHolder.getContext());
		this.pageData.getRequest().getSession().setAttribute("CURRENT_USER_NAME", userName);
	}
}

private void login(String userName) {
	SecurityContextHolder.setContext(new SecurityContextImpl());
	Set authorities = new HashSet();
	authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
	UserDetails userdetails = new User(userName, "", true, true, true, true, authorities);
	SpringSecurityUtils.saveUserDetailsToContext(userdetails, this.pageData.getRequest());
	this.pageData.getRequest().getSession().setAttribute("SPRING_SECURITY_CONTEXT",
			SecurityContextHolder.getContext());
	this.pageData.getRequest().getSession().setAttribute("CURRENT_USER_NAME", userName);
}

private void redirect2Page(Map<String, String> params) {
	System.out.println(params);
	try {
		String contentName = this.pageData.getRequest().getContextPath();

		String topage = processURL(params);

		String url = contentName + "/" + topage;
		MestarLogger.debug("自动登陆,URL:" + url);

		this.pageData.getResponse().addHeader("P3P", "CP=CAO PSA OUR");
		this.pageData.getResponse().sendRedirect(url);
	} catch (IOException e) {
		throw new MestarException("跳转失败!", e);
	}
}

private String processPassword(String psw, String ptype) {
	String spsw = "";
	if ((ptype == null) || ("crypt".equals(ptype))) {
		String mpsw = Crypt.decryptionData2(psw);

		spsw = MD5Util.MD5(mpsw);
	} else if ("md5".equals(ptype)) {
		spsw = psw;
	} else if ("min".equals(ptype)) {
		spsw = MD5Util.MD5(psw);
	}

	return spsw;
}

private String processURL(Map<String, String> params) {
	String topage = (String) params.get("_too");
	if (topage == null) {
		topage = "";
	}
	String urlParams = map2String(params);
	if (topage.indexOf("?") < 0) {
		urlParams = urlParams.replaceFirst("&", "?");
	}
	topage = topage + urlParams;

	return topage;
}

private String map2String(Map<String, String> params) {
	String paramStr = "";
	if ((params != null) && (params.size() > 0)) {
		for (String key : params.keySet()) {
			if (("bean".equals(key)) || ("method".equals(key)) || ("_u".equals(key)) || ("_p".equals(key))
					|| ("_to".equals(key)) || ("_pt".equals(key))) {
				continue;
			}

			try {
				paramStr = paramStr + "&" + key + "=" + URLEncoder.encode((String) params.get(key), "utf-8");
			} catch (Exception e) {
			}
		}
	}
	return paramStr;
}

static {
	try {
		intervalTime = Long.valueOf(
				Long.parseLong(EnvUtil.getMestarHomeApplicationProperties().getProperty("nopsw.login.interval"))
						* 60L * 1000L);
	} catch (Exception e) {
		System.out.println("在application.properties文件中没有读取到无密码登陆的时间间隔(nopsw.login.interval),系统自动取默认值10分钟");
		intervalTime = Long.valueOf(600000L);
	}
}

}

3 对外访问连接
http://localhost:8088/prj-wcdl/autoLoginController2!login.m?BBCloudBAMSession=123
维柴统一门户使用此连接,发送请求,后台验证当前用户 成功后跳转到 mes 首页