dongdingding
杜函宇 4 months ago
commit 2d04f54567

@ -0,0 +1,169 @@
package com.ruoyi.jjh.declaration.single.controller;
/**
* @author dong
* @since 2024/5/22 15:50
*/
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.domain.model.RegisterBody;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.security.context.AuthenticationContextHolder;
import com.ruoyi.framework.web.service.SysRegisterService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.jjh.declaration.single.dto.reqponse.UserMainResponse;
import com.ruoyi.jjh.declaration.single.dto.reqponse.UserResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.concurrent.TimeUnit;
/**
*
*/
@Api(tags = "单点登陆")
@RestController
@RequestMapping("/system/singlelogin")
public class SingleLoginController {
private static final Logger log = LoggerFactory.getLogger(SingleLoginController.class);
@Value("${url}")
private String url;
@Value("${infoUrl}")
private String infoUrl;
@Resource
private RedisCache redisCache;
@Resource
private AuthenticationManager authenticationManager;
@Resource
private TokenService tokenService;
@Resource
private SysRegisterService sysRegisterService;
/**
*
*
* @return
*/
@ApiOperation("统一登陆")
@GetMapping("/login")
public void login(HttpServletResponse response) throws IOException {
String clientUrl = "http://192.168.0.111:80/system/singlelogin/getInfo";
//变成参数模式,appid 用于校验提交的来源地址,生产环境会校验,试用环境暂不校验
String scUrl = "clientUrl=" + URLEncoder.encode(clientUrl, "UTF-8") + "&appid=b40b40e3-f188-4e00-b67a6ec5701ce02b";
//加密后的客户端地址
scUrl = Base64.getEncoder().encodeToString(scUrl.getBytes());
//最终跳转地址
String jumpurl = url + "&scUrl=" + URLEncoder.encode(scUrl, "UTF-8");
// 添加请求头
response.setHeader("Content-Type", "application/json");
response.setHeader("X-Requested-With", "XMLHttpRequest");
response.sendRedirect(jumpurl);
}
/**
*
*
* @return
*/
@ApiOperation(value = "获取用户信息",response = UserResponse.class)
@GetMapping("/getInfo")
public AjaxResult getInfo(@RequestParam("clientToken") String clientToken) throws Exception {
String url = infoUrl + "?clienttoken=" + clientToken;
HttpResponse response = HttpUtil.createGet(url).execute();
String responseBody = null;
// 获取响应状态码
int statusCode = response.getStatus();
if (statusCode == 200) {
// 获取响应内容
responseBody = response.body();
JSONObject jsonObj = JSONUtil.parseObj(responseBody);
JSONObject dataObj = jsonObj.getJSONObject("data");
JSONObject mainobj = dataObj.getJSONObject("mainbody");
UserResponse res = JSONUtil.toBean(dataObj, UserResponse.class);
UserMainResponse req = JSONUtil.toBean(mainobj, UserMainResponse.class);
// 将用户信息存储到Redis中
String key = "user:" + clientToken;
// 设置过期时间(可选)
int expirationSeconds = 24 * 60;
// 设置过期时间为8小时
redisCache.setCacheObject(key, res, expirationSeconds, TimeUnit.MINUTES);
String token = singleLogin(res.getUserid());
res.setToken(token);
res.setMain(req);
return AjaxResult.success(res);
} else {
log.error(response.body());
throw new ServiceException("未知异常请联系管理员");
}
}
private String singleLogin(String userId) {
// 用户验证
Authentication authentication;
try {
RegisterBody registerBody=new RegisterBody();
registerBody.setValue(String.valueOf(1));
registerBody.setUsername(userId);
registerBody.setPassword("admin123");
sysRegisterService.register(registerBody);
//新增user账号密码
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userId, "admin123");
AuthenticationContextHolder.setContext(authenticationToken);
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager.authenticate(authenticationToken);
} catch (Exception e) {
if (e instanceof BadCredentialsException) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(userId, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new UserPasswordNotMatchException();
} else {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(userId, Constants.LOGIN_FAIL, e.getMessage()));
throw new ServiceException(e.getMessage());
}
} finally {
AuthenticationContextHolder.clearContext();
}
AsyncManager.me().execute(AsyncFactory.recordLogininfor(userId, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
// 生成token
return tokenService.createToken(loginUser);
}
}

@ -0,0 +1,35 @@
package com.ruoyi.jjh.declaration.single.dto.reqponse;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author dong
* @since 2024/5/27 14:37
*/
@Data
@ApiModel("企业机构代码")
public class UserMainResponse {
/**
*
*/
@ApiModelProperty(value = "对应企业的组织机构代码")
private String organcode;
/**
*
*/
@ApiModelProperty(value = "对应企业的统一社会信用代码")
private String uscc;
/**
*
*/
@ApiModelProperty(value = "对应企业名称")
private String epname;
}

@ -0,0 +1,72 @@
package com.ruoyi.jjh.declaration.single.dto.reqponse;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
*
*
* @author dong
* @since 2024/5/27 10:55
*/
@ApiModel(value = "单点登录用户信息响应类")
@Data
public class UserResponse implements Serializable {
private static final long serialVersionUID = -5117946174934452302L;
/**
*
*/
@ApiModelProperty(value = "登录账号名")
private String loginname;
/**
*
*/
@ApiModelProperty(value = "用户姓名")
private String username;
/**
* id
*/
@ApiModelProperty(value = "用户id")
private String userid;
/**
*
*/
@ApiModelProperty(value = "权限")
private String email;
/**
*
*/
@ApiModelProperty(value = "手机号码")
private String mobileno;
/**
* ep-
*/
@ApiModelProperty(value = "用户类型ep-表示法人用户")
private String usertype;
/**
* legal-,admin-,user
*/
@ApiModelProperty(value = "角色类型legal-法定代表人,admin-管理员,user-业务经办")
private String roletype;
/**
* token
*/
@ApiModelProperty(value = "若依token")
private String token;
@ApiModelProperty(value = "企业机构代码")
private UserMainResponse main;
}

@ -0,0 +1,32 @@
package com.ruoyi.jjh.declaration.util;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
/**
* @author dong
* @since 2024/5/23 13:32
*/
public class AESEncryptor {
private static final String ALGORITHM = "AES";
private static final String SECRET_KEY = "2a20f065d22978998af65de11beeac5cad00cccf0a5d45abcff12eec0cd9311c"; // 密钥需要16个字符
public static String encrypt(String data) throws Exception {
SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] encryptedBytes = cipher.doFinal(data.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
}
public static String decrypt(String encryptedData) throws Exception {
SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(decryptedBytes);
}
}

@ -53,11 +53,12 @@ public class SysLoginController
* @return
*/
@PostMapping("/login")
public R<?> login(@RequestBody LoginBody loginBody)
{
Map<String, Object> login = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
loginBody.getUuid(),loginBody.getUserType());
return R.ok(login);
public AjaxResult login(@RequestBody LoginBody loginBody) {
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), loginBody.getUuid());
ajax.put(Constants.TOKEN, token);
return ajax;
}
/**

@ -125,3 +125,8 @@ xss:
excludes: /system/notice
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
#单点登陆url
url: https://qytt.sipac.gov.cn/api/usercenter/User/ssoLogin
#用户信息url
infoUrl: https://qytt.sipac.gov.cn/api/usercenter/User/getInfo

@ -68,7 +68,7 @@ public class UserConstants
*
*/
public static final int USERNAME_MIN_LENGTH = 2;
public static final int USERNAME_MAX_LENGTH = 20;
public static final int USERNAME_MAX_LENGTH = 40;
/**
*

@ -27,11 +27,25 @@ public class LoginBody
*/
private String uuid;
/**
*
*/
private String value;
/**
* 000102
*/
private String userType;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getUserType() {
return userType;
}

@ -111,7 +111,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
// 过滤请求
.authorizeRequests()
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
.antMatchers("/login", "/register", "/captchaImage").permitAll()
.antMatchers("/login", "/register", "/captchaImage","/system/singlelogin/**").permitAll()
// 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()

@ -31,7 +31,6 @@ import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Map;
/**
*
@ -74,7 +73,7 @@ public class SysLoginService {
* @param uuid
* @return
*/
public Map<String, Object> login(String username, String password, String code, String uuid, String userType) {
public String login(String username, String password, String code, String uuid) {
// 验证码校验
validateCaptcha(username, code, uuid);
// 登录前置校验
@ -99,30 +98,8 @@ public class SysLoginService {
}
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
// recordLoginInfo(loginUser.getUserId());
if (StringUtils.isNull(loginUser) || StringUtils.isNull(loginUser.getUserId())) {
addRecord(username, Constants.LOGIN_FAIL, "登录用户不存在");
throw new ServiceException("登录用户:" + username + " 不存在");
}
SysUser user = loginUser.getUser();
// 判断用户类型
if (!"admin".equals(username)) {
if (!userType.equals(user.getUserType())) {
throw new ServiceException("该用户类型错误");
}
}
recordLoginInfo(loginUser.getUserId());
if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
addRecord(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除");
throw new ServiceException("对不起,您的账号:" + username + " 已被删除");
}
if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
addRecord(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员");
throw new ServiceException("对不起,您的账号:" + username + " 已停用");
}
// sysPasswordService.validate(user);
addRecord(username, Constants.LOGIN_SUCCESS, "登录成功");
// 生成token
return tokenService.createToken(loginUser);
}

@ -51,7 +51,7 @@ public class SysRegisterService
// 验证码开关
boolean captchaEnabled = configService.selectCaptchaEnabled();
if (captchaEnabled)
if (captchaEnabled && registerBody.getValue() == null)
{
validateCaptcha(username, registerBody.getCode(), registerBody.getUuid());
}

@ -111,8 +111,7 @@ public class TokenService
* @param loginUser
* @return
*/
public Map<String, Object> createToken(LoginUser loginUser)
{
public String createToken(LoginUser loginUser) {
String token = IdUtils.fastUUID();
loginUser.setToken(token);
setUserAgent(loginUser);
@ -120,13 +119,7 @@ public class TokenService
Map<String, Object> claims = new HashMap<>();
claims.put(Constants.LOGIN_USER_KEY, token);
String token1 = createToken(claims);
// 接口返回信息
Map<String, Object> rspMap = new HashMap<>();
rspMap.put("access_token", token1);
rspMap.put("expires_in", expireTime);
return rspMap;
return createToken(claims);
}
/**

@ -63,4 +63,5 @@ public class UserDetailsServiceImpl implements UserDetailsService
{
return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
}
}

Loading…
Cancel
Save