package com.vci.web.controller;
|
|
import com.vci.starter.web.annotation.controller.VciUnCheckRight;
|
import com.vci.starter.web.annotation.log.VciBusinessLog;
|
import com.vci.starter.web.constant.TokenKeyConstant;
|
import com.vci.starter.web.pagemodel.BaseResult;
|
import com.vci.starter.web.pagemodel.RequestClientInfo;
|
import com.vci.starter.web.pagemodel.SessionInfo;
|
import com.vci.starter.web.util.LangBaseUtil;
|
import com.vci.starter.web.util.MessageUtils;
|
import com.vci.starter.web.util.VciBaseUtil;
|
import com.vci.starter.web.util.WebThreadLocalUtil;
|
import com.vci.web.bo.LoginResultBO;
|
import com.vci.web.dto.LoginUserDTO;
|
import com.vci.web.service.LoginServiceI;
|
import eu.bitwalker.useragentutils.*;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Controller;
|
import org.springframework.util.CollectionUtils;
|
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.servlet.ModelAndView;
|
|
import javax.servlet.http.Cookie;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.security.Principal;
|
import java.util.*;
|
|
/**
|
* 登录控制器
|
* @author weidy
|
* @date 2021-1-28
|
*/
|
@Controller
|
@RequestMapping("/framework/loginController")
|
@VciBusinessLog(modelName="登录服务")
|
public class LoginController{
|
|
/**
|
* 登录服务
|
*/
|
@Autowired
|
private LoginServiceI loginService;
|
|
/**
|
* 登录,这个地方主要是为了登录后单独的业务
|
* @param userDTO 用户的对象
|
* @param request 请求对象
|
* @param clientInfo 客户端的信息
|
* @return 执行结果
|
*/
|
@VciBusinessLog(operateName="登录")
|
@PostMapping(value = "/login")
|
@ResponseBody
|
@VciUnCheckRight()
|
public BaseResult login(LoginUserDTO userDTO, HttpServletRequest request, RequestClientInfo clientInfo){
|
VciBaseUtil.alertNotNull(userDTO,"用户对象",clientInfo,"请求客户端信息");
|
wrapperBrowserInfo(clientInfo,request);
|
LoginResultBO loginResultBO = loginService.login(userDTO,clientInfo);
|
if(loginResultBO.isSuccess()){
|
return BaseResult.success(loginResultBO);
|
}else{
|
BaseResult result = BaseResult.fail(loginResultBO.getFailMsg());
|
if(StringUtils.isBlank(loginResultBO.getFailMsg())){
|
result.setMsg(MessageUtils.get(loginResultBO.getFailCode(),loginResultBO.getFailMsgArray()));
|
}
|
result.setObj(loginResultBO);
|
return result;
|
}
|
}
|
|
/**
|
* CAS的单点登录
|
* 1. cas单点登录,则从userPrincipal里获取
|
* 2. 在头里面加iv-user
|
* 3. 在request里面放用户
|
* @param request 请求的对象
|
* @param response 响应对象
|
* @return html的名字的前缀,具体是Jsp还是html,是spring-mvc里配置的
|
*/
|
@VciBusinessLog(operateName="单点登录")
|
@RequestMapping("/singleLoginCas")
|
@VciUnCheckRight()
|
public ModelAndView singleLoginCas(HttpServletRequest request,HttpServletResponse response){
|
return doSingleLogin(request,response,"");
|
}
|
|
/**
|
* 执行单点登录
|
* @param request 请求的信息
|
* @param userParam 用户的参数名字
|
* @return 返回main.html
|
*/
|
private ModelAndView doSingleLogin(HttpServletRequest request, HttpServletResponse response,String userParam){
|
String msg = "";
|
String token = "";
|
if(request.getSession() == null){
|
msg = "session已经过期或不存在,你可能需要重新执行单点登录";
|
}else {
|
String username = "";
|
Principal principal = request.getUserPrincipal();
|
if(principal!=null){
|
Object ivUser = principal.getName();
|
if (ivUser != null ) {
|
username = ivUser.toString();
|
}
|
}
|
//用户的参数
|
if(StringUtils.isBlank(userParam)){
|
userParam = request.getParameter("userParam");
|
}
|
userParam = StringUtils.isBlank(userParam)?"iv-user":userParam;
|
if(StringUtils.isBlank(username)){
|
//不是cas的方式,而是头的方式
|
username = request.getHeader(userParam);
|
}
|
if(StringUtils.isBlank(username)){
|
//看看是不参数
|
username = request.getParameter(userParam);
|
}
|
if(StringUtils.isBlank(username)){
|
msg = "没有获取到用户的信息";
|
}else{
|
RequestClientInfo clientInfo =new RequestClientInfo();
|
wrapperBrowserInfo(clientInfo,request);
|
LoginUserDTO userDTO = new LoginUserDTO();
|
userDTO.setUserId(username);
|
try {
|
LoginResultBO loginResultBO = loginService.singleLogin(userDTO, clientInfo);
|
if(!loginResultBO.isSuccess()){
|
msg = loginResultBO.getFailMsg();
|
}else {
|
token = loginResultBO.getTokenVO().getAccessToken();
|
}
|
}catch (Throwable e){
|
msg = LangBaseUtil.getErrorMsg(e);
|
}
|
}
|
}
|
Enumeration<?> parameterNames = request.getParameterNames();
|
Map<String,String> paramMap = new HashMap<>();
|
while (parameterNames.hasMoreElements()){
|
String paramName = (String)parameterNames.nextElement();
|
String value = request.getParameter(paramName);
|
if(!userParam.equalsIgnoreCase(paramName)) {
|
paramMap.put(paramName, value);
|
}
|
//sb.append("&" + paramName + "=" + value);
|
}
|
String html = request.getParameter("html");
|
if(StringUtils.isBlank(html)){
|
html = "main";
|
}
|
ModelAndView view = new ModelAndView();
|
Cookie cookie = new Cookie("msg", msg);
|
cookie.setPath("/");
|
response.addCookie(cookie);
|
Cookie cookie1 = new Cookie(TokenKeyConstant.USER_TOKEN_KEY, token);
|
cookie1.setPath("/");
|
response.addCookie(cookie1);
|
view.addAllObjects(paramMap);
|
view.setViewName("redirect:/" + html + ".html");
|
|
return view;
|
//特别注意,单点登录一定在运行环境里调试,开发环境没有这个文件
|
}
|
|
/**
|
* 执行单点登录,根据username
|
* @param request 请求的信息
|
* @param username 用户的参数名字
|
* @return 返回main.html
|
*/
|
public BaseResult doSingleLoginByUsername(HttpServletRequest request, HttpServletResponse response,String username){
|
String msg = "";
|
String token = "";
|
if(request.getSession() == null){
|
msg = "session已经过期或不存在,你可能需要重新执行单点登录";
|
return BaseResult.fail(msg);
|
}else {
|
|
if(StringUtils.isBlank(username)){
|
msg = "没有获取到用户的信息";
|
return BaseResult.fail(msg);
|
}else{
|
RequestClientInfo clientInfo =new RequestClientInfo();
|
wrapperBrowserInfo(clientInfo,request);
|
LoginUserDTO userDTO = new LoginUserDTO();
|
userDTO.setUserId(username);
|
try {
|
LoginResultBO loginResultBO = loginService.singleLogin(userDTO, clientInfo);
|
if(!loginResultBO.isSuccess()){
|
msg = loginResultBO.getFailMsg();
|
return BaseResult.fail(msg);
|
}else {
|
token = loginResultBO.getTokenVO().getAccessToken();
|
msg="登录成功!";
|
}
|
}catch (Throwable e){
|
msg = LangBaseUtil.getErrorMsg(e);
|
}
|
}
|
}
|
|
|
return BaseResult.success(msg);
|
//特别注意,单点登录一定在运行环境里调试,开发环境没有这个文件
|
}
|
|
/**
|
* 使用用户名来执行单点登录
|
* @param request 请求对象
|
* @param response 响应对象
|
* @return main.html
|
*/
|
@RequestMapping("/singleLoginByUsername")
|
@VciUnCheckRight
|
@VciBusinessLog(operateName="单点登录")
|
public ModelAndView singleLoginByUsername(HttpServletRequest request,HttpServletResponse response){
|
return doSingleLogin(request,response,"username");
|
}
|
|
|
|
/**
|
* 获取客户端请求信息,为了隔绝在server层使用request
|
* @param request 请求对象
|
* @param clientInfo 客户端信息
|
*/
|
private void wrapperBrowserInfo(RequestClientInfo clientInfo,HttpServletRequest request) {
|
UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
|
if(StringUtils.isBlank(clientInfo.getIpaddress())){
|
//找IP地址
|
clientInfo.setIpaddress(getIpAddressFromRequest(request));
|
}
|
if(userAgent !=null) {
|
Browser browser = userAgent.getBrowser();
|
OperatingSystem os = userAgent.getOperatingSystem();
|
|
clientInfo.setOsversion(os != null ? os.getName() : "");
|
clientInfo.setBrowser(browser != null ? browser.getName() : "IE");
|
String version = "";
|
if (browser != null) {
|
Version version1 = browser.getVersion(request.getHeader("User-Agent"));
|
if (version1 != null) {
|
version = version1.getVersion();
|
}
|
}
|
clientInfo.setBrowserversion(version);
|
if (os != null) {
|
clientInfo.setRequestType(os.getDeviceType().getName());
|
if (DeviceType.COMPUTER.getName().equals(clientInfo.getRequestType())) {
|
clientInfo.setRequestType("browser");
|
}
|
}
|
}
|
}
|
|
/**
|
* 从请求中获取ip地址,为了隔绝在server层使用request
|
* @param request 请求对象
|
* @return ip地址,没有找到默认为127.0.0.1
|
*/
|
private String getIpAddressFromRequest(HttpServletRequest request){
|
String ip = request.getHeader("X-Forwarded-For");
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
ip = request.getHeader("Proxy-Client-IP");
|
}
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
ip = request.getHeader("WL-Proxy-Client-IP");
|
}
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
ip = request.getHeader("HTTP_CLIENT_IP");
|
}
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
}
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
ip = request.getRemoteAddr();
|
}
|
if (ip == null || ip.length() == 0 || ip.indexOf("0:0:0:0:0:0:0:1") >-1) {
|
//0:0:0:0:0:0:0:1是本机在访问
|
ip = "127.0.0.1";
|
}
|
return ip;
|
}
|
|
/**
|
* 获取用户的会话信息
|
* @return success为true表示获取成功,否则msg是错误信息,obj属性是获取的会话对象信息
|
*/
|
@VciUnCheckRight
|
@PostMapping("/getSessionInfo")
|
@ResponseBody
|
public BaseResult getSessionInfo(){
|
BaseResult<SessionInfo> json = new BaseResult<>();
|
json.setObj(WebThreadLocalUtil.getCurrentUserSessionInfoInThread());
|
if(json.getObj()!=null){
|
json.setSuccess(true);
|
}
|
return json;
|
}
|
|
/**
|
* 执行退出
|
* @param request 请求对象
|
* @return success为true表示退出成功,前端不需要判断结果
|
*/
|
@VciUnCheckRight
|
@PostMapping("/logout")
|
@ResponseBody
|
public BaseResult logout(HttpServletRequest request){
|
String userToken = request.getHeader(TokenKeyConstant.USER_TOKEN_KEY);
|
loginService.logout(userToken);
|
return BaseResult.success();
|
}
|
}
|