Commit 01135a00 by WeiCong

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

parent 3c702010
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);
}
}
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