package com.xiaopeng.account.controller; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.xiaopeng.account.service.ISysGroupService; import com.xiaopeng.account.service.impl.SysLoginService; import com.xiaopeng.account.vo.OIDCAppUserInfoVo; import com.xiaopeng.account.vo.OIDCUserInfoVo; import com.xiaopeng.account.vo.SSOToken; import com.xiaopeng.api.model.account.SysRole; import com.xiaopeng.api.vo.account.LoginOperationUser; import com.xiaopeng.api.vo.account.LoginUser; import com.xiaopeng.common.core.constant.CacheConstants; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.common.core.exception.ServiceException; import com.xiaopeng.common.core.utils.JwtUtils; import com.xiaopeng.common.redis.service.RedisService; import com.xiaopeng.common.security.service.TokenService; import io.jsonwebtoken.Claims; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.text.ParseException; import java.time.Instant; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @Slf4j @RestController @RequestMapping("") public class XtigerSSOController { @Value("${xiaopeng.xtiger.sso.issuer}") private String issuer; @Value("${xiaopeng.xtiger.sso.appId}") private String appId; @Value("${ali.push.key:335666352}") private String aliPushKey; @Value("${ali.push.secret:0252ebde2dc84f63aebd41f757f213d7}") private String aliPushSecret; @Autowired private TokenService tokenService; @Autowired private SysLoginService sysLoginService; @Autowired private ISysGroupService sysGroupService; @Autowired private RedisService redisService; /** * 翼虎web登录重定向接口 * 通过code换取token * * @param code * @param state */ @GetMapping("/base/v1/ssoAuthSdk/sysLogin") public R sysLogin(String code, String state, HttpServletRequest request) { log.info("翼虎登录重定向接口, code: {}, state: {}", code, state); HttpRequest post = HttpUtil.createPost(issuer + "/oidc/token/v2"); post.form("client_id", appId); post.form("code", code); post.form("grant_type", "authorization_code"); HttpResponse execute = post.execute(); if(!execute.isOk()){ throw new ServiceException("登录失败,请稍后重试。"); } String body = execute.body(); log.info("翼虎登录重定向接口, 返回结果: {}", body); SSOToken ssoToken = JSON.parseObject(body, SSOToken.class); String accessToken = ssoToken.getAccessToken(); OIDCUserInfoVo userInfo = getUserInfo(accessToken); return login(userInfo, request); } /** *翼虎app登录换取本系统token * @param request * @return */ @GetMapping("/maintenance-app/ssoAuthSdk/appLogin") public R appLogin(Integer deviceType, HttpServletRequest request){ String accessTokenHeader = request.getHeader("XP-TOKEN"); log.info("运维APP登录, accessTokenHeader: {}", accessTokenHeader); String accessToken = StringUtils.isEmpty(accessTokenHeader) ? null : accessTokenHeader.replace("Bearer ", ""); if(StringUtils.isEmpty(accessToken)){ throw new ServiceException("登录失败,请稍后重试。"); } OIDCAppUserInfoVo userInfo = getAppUserInfo(request, accessToken); return appLogin(userInfo, deviceType, request); } /** *翼虎app登录换取本系统token * @return */ @PostMapping("/maintenance-app/ssoAuthSdk/appLoginOut") public R appLoginOut(){ LoginOperationUser loginOperationUser = tokenService.getLoginOperationUser(); if(null == loginOperationUser){ throw new ServiceException("操作失败,请稍后重试。"); } String token = loginOperationUser.getToken(); redisService.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + token); return R.ok(); } public OIDCUserInfoVo getUserInfo(String accessToken) { log.info("翼虎登录使用token获取用户信息"); HttpRequest post = HttpUtil.createGet(issuer + "/oidc/userinfo"); post.header("Authorization", "Bearer " + accessToken); HttpResponse execute = post.execute(); if(!execute.isOk()){ throw new ServiceException("登录失败,请稍后重试。"); } String body = execute.body(); log.info("翼虎登录使用token获取用户信息, 返回结果: {}", body); OIDCUserInfoVo ssoToken = JSON.parseObject(body, OIDCUserInfoVo.class); return ssoToken; } public OIDCAppUserInfoVo getAppUserInfo(HttpServletRequest request, String accessToken) { log.info("APP翼虎登录使用token获取用户信息"); HttpRequest post = HttpUtil.createGet(issuer + "/xtiger/app/userinfo"); post.header("Authorization", "Bearer " + accessToken); post.header("Content-Type", "application/json"); post.header("XT-Client-Type", request.getHeader("XT-Client-Type")); post.header("XT-DeviceId", request.getHeader("XT-DeviceId")); post.header("XT-AppId", request.getHeader("XT-AppId")); post.header("XT-Signature", request.getHeader("XT-Signature")); post.header("XT-Nonce", request.getHeader("XT-Nonce")); post.header("Client-Type", "PC"); log.info("请求参数:{}", post.headers()); HttpResponse execute = post.execute(); if(!execute.isOk()){ throw new ServiceException("登录失败,请稍后重试。"); } String body = execute.body(); log.info("APP翼虎登录使用token获取用户信息, 返回结果: {}", body); JSONObject jsonObject = JSON.parseObject(body); Integer code = jsonObject.getInteger("code"); if(null != code && 200 != code){ throw new ServiceException(jsonObject.getString("msg")); } OIDCAppUserInfoVo ssoToken = jsonObject.getObject("data", OIDCAppUserInfoVo.class); return ssoToken; } public R login(OIDCUserInfoVo userInfo, HttpServletRequest request) { // 用户登录 LoginUser loginUser = sysLoginService.login(userInfo.getPhone_number(), request); boolean phoneDesensitization = sysGroupService.getPhoneDesensitization(); loginUser.setPhoneDesensitizationExempt(phoneDesensitization); HashMap map = new HashMap<>(); map.put("token", tokenService.createToken(loginUser)); map.put("info", loginUser); // 修改用户最后登录时间 return R.ok(map); } public R appLogin(OIDCAppUserInfoVo userInfo, Integer deviceType, HttpServletRequest request){ LoginOperationUser loginUser = sysLoginService.verificationCodeLogin(userInfo.getPhone(), deviceType, request); HashMap map = new HashMap<>(); map.put("token", tokenService.createOperationUserToken(loginUser)); map.put("info", loginUser); Map thirdInfo = new HashMap<>(); thirdInfo.put("pushKey", aliPushKey); thirdInfo.put("pushSecret", aliPushSecret); map.put("thirdInfo", thirdInfo); return R.ok(map); } }