release:单点登录初版

master
路明慧 10 months ago
parent 9c24dd9be9
commit 1e76990117
  1. 6
      itaxBase-admin/pom.xml
  2. 219
      itaxBase-admin/src/main/java/com/dxhy/itax/modules/common/controller/WebController.java
  3. 10
      itaxBase-admin/src/main/java/com/dxhy/itax/modules/management/controller/SysUserController.java
  4. 2
      itaxBase-admin/src/main/resources/logback-spring.xml
  5. 7
      itaxBase-common/pom.xml
  6. 2
      itaxBase-common/src/main/java/com/dxhy/itax/dao/SysUserDao.java
  7. 18
      itaxBase-common/src/main/java/com/dxhy/itax/model/JwtToken.java
  8. 57
      itaxBase-common/src/main/java/com/dxhy/itax/service/OATokenService.java
  9. 2
      itaxBase-common/src/main/java/com/dxhy/itax/service/UserService.java
  10. 9
      itaxBase-common/src/main/java/com/dxhy/itax/service/impl/UserServiceImpl.java
  11. 4
      itaxBase-common/src/main/resources/mapper/SysUserDao.xml

@ -20,6 +20,12 @@
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
<!-- Spring Cloud Nacos Service Config --> <!-- Spring Cloud Nacos Service Config -->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>

@ -4,6 +4,8 @@ import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dxhy.itax.annotation.SysLog; import com.dxhy.itax.annotation.SysLog;
import com.dxhy.itax.config.*; import com.dxhy.itax.config.*;
@ -16,8 +18,10 @@ import com.dxhy.itax.dto.response.QsTypeResponse;
import com.dxhy.itax.dto.response.TabInfoResponse; import com.dxhy.itax.dto.response.TabInfoResponse;
import com.dxhy.itax.dto.response.XxTabinfoResponse; import com.dxhy.itax.dto.response.XxTabinfoResponse;
import com.dxhy.itax.entity.CountItemConfig; import com.dxhy.itax.entity.CountItemConfig;
import com.dxhy.itax.entity.SysUserEntity;
import com.dxhy.itax.entity.SystenConfiguration; import com.dxhy.itax.entity.SystenConfiguration;
import com.dxhy.itax.enums.*; import com.dxhy.itax.enums.*;
import com.dxhy.itax.model.JwtToken;
import com.dxhy.itax.model.LoginModel; import com.dxhy.itax.model.LoginModel;
import com.dxhy.itax.model.UserInfo; import com.dxhy.itax.model.UserInfo;
import com.dxhy.itax.openapi.model.ShortMessageRequest; import com.dxhy.itax.openapi.model.ShortMessageRequest;
@ -40,6 +44,7 @@ import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
@ -49,7 +54,10 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -104,6 +112,12 @@ public class WebController {
@Autowired @Autowired
private ItaxAdminConfig itaxAdminConfig; private ItaxAdminConfig itaxAdminConfig;
@Autowired
private OATokenService oaTokenService;
@Value("${oauth.whitelist}")
private String whitelist;
private Set<String> urlSet = new HashSet<String>(); private Set<String> urlSet = new HashSet<String>();
private final String firCount = "1"; private final String firCount = "1";
@ -156,6 +170,211 @@ public class WebController {
} }
} }
@RequestMapping("/otherLogin")
public void otherLogin(LoginModel loginModel,HttpServletResponse response) throws IOException {
//开始执行登录
String username = AESUtil.aesDecrypt(loginModel.getDxhyu());
log.info("用户{},登录开始", username);
ReturnT<UserInfo> result = userService.findUser(loginModel.getDxhyu(), loginModel.getDxhyp());
log.info("用户{},登录结果:{}", username, JSON.toJSONString(result));
if (result.getCode() != SUCCESS_CODE){
response.setCharacterEncoding("UTF-8");
response.getWriter().write(result.getMsg());
return;
}
boolean ifRem = false;
SsoUser xxlUser = new SsoUser();
xxlUser.setUserId(result.getData().getUserid());
UserInfoRequestDto userInfoRequestDto = new UserInfoRequestDto();
userInfoRequestDto.setUserId(result.getData().getUserid());
Result result1 = userService.queryUserInfo(userInfoRequestDto);
try {
if (result1.get("code").equals("0000")) {
xxlUser = JsonUtils.getInstance().parseObject(result1.get("data").toString(), SsoUser.class);
if(CollectionUtil.isNotEmpty(xxlUser.getTaxplayercodeDeptList())){
xxlUser.setCurrentDeptId(xxlUser.getTaxplayercodeDeptList().get(0).getDeptId());
}
log.info("获取到的用户信息{},{}", xxlUser.getUserId());
}
} catch (Exception ex) {
log.info("获取菜单异常" + JSONObject.toJSONString(ex));
log.info("用户{},登录失败", username);
}
xxlUser.setUsername(username);
xxlUser.setVersion(UUID.randomUUID().toString().replaceAll("-", ""));
xxlUser.setExpireMinite(SsoLoginStore.getRedisExpireMinite());
xxlUser.setExpireFreshTime(System.currentTimeMillis());
// 2、make session id
String sessionId = SsoSessionIdHelper.makeSessionId(xxlUser);
log.info("存储的用户信息{},{}", xxlUser.getUserId());
// 3、login, store storeKey + cookie sessionId
SsoWebLoginHelper.login(response, sessionId, xxlUser, ifRem);
log.info("用户{},登录成功,sessionID是{}", username, sessionId);
//4.更新last_login_time
userService.updateLastLoginTime(xxlUser.getUserId());
String url = itaxAdminConfig.getItaxbenchfront();
log.info("外放登陆跳转地址:{}", url);
response.sendRedirect(url);
}
@RequestMapping("/singleLogin")
public void reOA(@RequestParam Map<String,Object> params,HttpServletResponse response) throws IOException {
Object code = params.get("code");
if(code==null){
log.info("单电登陆code为空");
response.setCharacterEncoding("UTF-8");
response.getWriter().write("<!DOCTYPE html> \n" +
"<html lang=\"zh-CN\"> \n" +
"<head> \n" +
" <meta charset=\"UTF-8\"> \n" +
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"> \n" +
" <title>发票系统单点登陆结果</title> \n" +
" <style> \n" +
" body { \n" +
" font-family: Arial, sans-serif; \n" +
" margin: 40px; \n" +
" padding: 20px; \n" +
" background-color: #f4f4f4; \n" +
" color: #333; \n" +
" } \n" +
" .container { \n" +
" background-color: #fff; \n" +
" padding: 20px; \n" +
" border-radius: 8px; \n" +
" box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); \n" +
" } \n" +
" h2 { \n" +
" color: #5cb85c; \n" +
" } \n" +
" /* 添加这个类来指定查询结果提示的颜色为红色 */ \n" +
" .result-error { \n" +
" color: red; \n" +
" } \n" +
" p { \n" +
" margin: 10px 0; \n" +
" } \n" +
" </style> \n" +
"</head> \n" +
"<body> \n" +
" <div class=\"container\"> \n" +
" <h2 class=\"result-error\">单点登陆失败</h2>\n" +
" <!-- 使用新的类名来指定颜色 --> \n" +
" <p>罗欣统一认证系统未返回发票系统有效参数</p>\n" +
" <p>请尝试以下解决方案:</p> \n" +
" <ul> \n" +
" <li>联系运维人员,排查相关问题。</li>\n" +
" </ul> \n" +
" </div> \n" +
"</body> \n" +
"</html>");
return;
}
log.info("单点登陆code"+code.toString());
JwtToken jwt = oaTokenService.getOauth2Token(code.toString());
DecodedJWT decode = JWT.decode(jwt.getAccessToken());
String username = decode.getClaim("preferred_username").asString();
log.debug("单电登陆解析accessToken:{}",JSON.toJSONString(decode));
//开始执行登录
log.info("用户{},登录开始", username);
boolean ifRem = false;
SysUserEntity user = userService.findUserByName(username);
log.info("用户查询结果{}",JSON.toJSONString(user));
if (user == null){
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
writer.write("<!DOCTYPE html> \n" +
"<html lang=\"zh-CN\"> \n" +
"<head> \n" +
" <meta charset=\"UTF-8\"> \n" +
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"> \n" +
" <title>发票系统单点登陆结果</title> \n" +
" <style> \n" +
" body { \n" +
" font-family: Arial, sans-serif; \n" +
" margin: 40px; \n" +
" padding: 20px; \n" +
" background-color: #f4f4f4; \n" +
" color: #333; \n" +
" } \n" +
" .container { \n" +
" background-color: #fff; \n" +
" padding: 20px; \n" +
" border-radius: 8px; \n" +
" box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); \n" +
" } \n" +
" h2 { \n" +
" color: #5cb85c; \n" +
" } \n" +
" /* 添加这个类来指定查询结果提示的颜色为红色 */ \n" +
" .result-error { \n" +
" color: red; \n" +
" } \n" +
" p { \n" +
" margin: 10px 0; \n" +
" } \n" +
" </style> \n" +
"</head> \n" +
"<body> \n" +
" <div class=\"container\"> \n" +
" <h2 class=\"result-error\">单点登陆失败</h2>\n" +
" <!-- 使用新的类名来指定颜色 --> \n" +
" <p>您在发票系统中的信息未找到。</p>\n" +
" <p>请尝试以下解决方案:</p> \n" +
" <ul> \n" +
" <li>联系运维人员,请求配置相关信息。</li>\n" +
" </ul> \n" +
" </div> \n" +
"</body> \n" +
"</html>");
return;
}
SsoUser xxlUser = new SsoUser();
xxlUser.setUserId(user.getUserId());
UserInfoRequestDto userInfoRequestDto = new UserInfoRequestDto();
userInfoRequestDto.setUserId(user.getUserId());
Result result1 = userService.queryUserInfo(userInfoRequestDto);
try {
if (result1.get("code").equals("0000")) {
xxlUser = JsonUtils.getInstance().parseObject(result1.get("data").toString(), SsoUser.class);
if(CollectionUtil.isNotEmpty(xxlUser.getTaxplayercodeDeptList())){
xxlUser.setCurrentDeptId(xxlUser.getTaxplayercodeDeptList().get(0).getDeptId());
}
log.info("获取到的用户信息{},{}", xxlUser.getUserId());
}
} catch (Exception ex) {
log.info("获取菜单异常" + JSONObject.toJSONString(ex));
log.info("用户{},登录失败", username);
}
xxlUser.setUsername(user.getUsername());
xxlUser.setVersion(UUID.randomUUID().toString().replaceAll("-", ""));
xxlUser.setExpireMinite(SsoLoginStore.getRedisExpireMinite());
xxlUser.setExpireFreshTime(System.currentTimeMillis());
// 2、make session id
String sessionId = SsoSessionIdHelper.makeSessionId(xxlUser);
log.info("存储的用户信息{},{}", xxlUser.getUserId());
// 3、login, store storeKey + cookie sessionId
SsoWebLoginHelper.login(response, sessionId, xxlUser, ifRem);
log.info("用户{},登录成功,sessionID是{}", username, sessionId);
//4.更新last_login_time
userService.updateLastLoginTime(xxlUser.getUserId());
String url = itaxAdminConfig.getItaxbenchfront();
log.info("单点登陆跳转地址:{}", url);
response.sendRedirect(url);
}
/** /**
* Login * Login
* 实现单点登录并进行跳转方法 * 实现单点登录并进行跳转方法

@ -3,6 +3,8 @@ package com.dxhy.itax.modules.management.controller;
import cn.hutool.core.util.ZipUtil; import cn.hutool.core.util.ZipUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.dxhy.itax.util.AesEncryptUtil;
import com.dxhy.itax.utils.AESUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.dxhy.itax.annotation.SysLog; import com.dxhy.itax.annotation.SysLog;
import com.dxhy.itax.config.ItaxAdminConfig; import com.dxhy.itax.config.ItaxAdminConfig;
@ -29,6 +31,8 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
@ -268,5 +272,11 @@ public class SysUserController {
return userService.updatePassword(userPasswordDto); return userService.updatePassword(userPasswordDto);
} }
public static void main(String[] args) throws UnsupportedEncodingException {
String ysq = AESUtil.aesEncrypt("ysq");
String s = AESUtil.aesEncrypt("admin@123");
System.out.println("dxhyu="+ysq+"&dxhyp="+s);
}
} }

@ -5,7 +5,7 @@
<property name="LOG_PATH" value="@logging.file@"/> <property name="LOG_PATH" value="@logging.file@"/>
<property name="LOG_LEVEL" value="@logging.level@"/> <property name="LOG_LEVEL" value="debug"/>
<!--设置系统日志目录--> <!--设置系统日志目录-->
<property name="APP_DIR" value="itax-admin"/> <property name="APP_DIR" value="itax-admin"/>
<!-- 记录日志天数 --> <!-- 记录日志天数 -->

@ -11,6 +11,13 @@
<description>itaxBase-common</description> <description>itaxBase-common</description>
<dependencies> <dependencies>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>

@ -198,4 +198,6 @@ public interface SysUserDao extends BaseMapper<SysUserEntity> {
Integer queryCount(@Param("deptIdList")List<Long> deptIdList); Integer queryCount(@Param("deptIdList")List<Long> deptIdList);
SysUserEntity findUserByName(String userName);
} }

@ -0,0 +1,18 @@
package com.dxhy.itax.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class JwtToken {
@JsonProperty("access_token")
private String accessToken;
@JsonProperty("refresh_token")
private String refreshToken;
}

@ -0,0 +1,57 @@
package com.dxhy.itax.service;
import com.alibaba.fastjson.JSON;
import com.dxhy.itax.model.JwtToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
@Slf4j
@Component
public class OATokenService {
@Value("${spring.security.oauth2.client.provider.custom.token-uri}")
String oauth2TokenUrl;
@Value("${spring.security.oauth2.client.registration.custom.authorization-grant-type}")
String grant_type;
@Value("${spring.security.oauth2.client.registration.custom.client-id}")
String client_id;
@Value("${spring.security.oauth2.client.registration.custom.client-secret}")
String client_secret;
@Value("${spring.security.oauth2.client.registration.custom.redirect-uri}")
String redirect_uri;
public JwtToken getOauth2Token(String authCode) {
RestTemplate simpleRestTemplate = new RestTemplateBuilder()
.build();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("grant_type", grant_type);
map.add("client_id", client_id);
map.add("client_secret", client_secret);
map.add("code", authCode);
map.add("redirect_uri", redirect_uri);
log.info("请求参数:" + JSON.toJSONString(map));
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
ResponseEntity<JwtToken> res = simpleRestTemplate.exchange(
oauth2TokenUrl,
HttpMethod.POST,
request,
JwtToken.class
);
return res.getBody();
}
}

@ -177,4 +177,6 @@ public interface UserService {
* @param sysUserEntitys * @param sysUserEntitys
*/ */
void impUserCheck(List<SysUserEntity> sysUserEntitys); void impUserCheck(List<SysUserEntity> sysUserEntitys);
SysUserEntity findUserByName(String userName);
} }

@ -466,7 +466,8 @@ public class UserServiceImpl implements UserService {
sysUserEntity.setMobile(AESUtil.aesEncrypt(sysUserEntity.getMobile())); sysUserEntity.setMobile(AESUtil.aesEncrypt(sysUserEntity.getMobile()));
//密码base64 md5 //密码base64 md5
SysUserEntity finalUserEntity = ItaxBeanTransitionUtils.md5AndBase64password(sysUserEntity, adminUserOperateDto.getPassword(),itaxConfig.userCenterType()); SysUserEntity finalUserEntity = ItaxBeanTransitionUtils.md5AndBase64password(sysUserEntity, adminUserOperateDto.getPassword(),itaxConfig.userCenterType());
finalUserEntity.setLoginCount(2);
finalUserEntity.setLastLoginTime(new Date());
//添加用户主体 //添加用户主体
log.debug("添加用户"+ JSONObject.toJSONString(finalUserEntity)); log.debug("添加用户"+ JSONObject.toJSONString(finalUserEntity));
sysUserDao.insert(finalUserEntity); sysUserDao.insert(finalUserEntity);
@ -1087,6 +1088,7 @@ public class UserServiceImpl implements UserService {
UserInfo queryPara = new UserInfo(); UserInfo queryPara = new UserInfo();
queryPara.setUsername(username); queryPara.setUsername(username);
UserInfo userInfo = sysUserDao.seletUserByUAP(queryPara,ConfigureConstant.STRING_1); UserInfo userInfo = sysUserDao.seletUserByUAP(queryPara,ConfigureConstant.STRING_1);
log.info("用户名:{},密码:{},查询用户信息:{}", username, password, JSONObject.toJSONString(userInfo));
if (userInfo == null) { if (userInfo == null) {
return new ReturnT<UserInfo>(ReturnT.FAIL_CODE, "用户名或密码不正确!"); return new ReturnT<UserInfo>(ReturnT.FAIL_CODE, "用户名或密码不正确!");
} }
@ -1267,4 +1269,9 @@ public class UserServiceImpl implements UserService {
} }
} }
@Override
public SysUserEntity findUserByName(String userName) {
return sysUserDao.findUserByName(userName);
}
} }

@ -527,4 +527,8 @@
</if> </if>
</where> </where>
</select> </select>
<select id="findUserByName" parameterType="java.lang.String" resultType="com.dxhy.itax.entity.SysUserEntity">
select * from sys_user where username = #{userName}
</select>
</mapper> </mapper>
Loading…
Cancel
Save