Files
pqs/pqs-auth/src/main/java/com/njcn/auth/controller/AuthController.java

141 lines
6.2 KiB
Java
Raw Normal View History

2022-06-21 20:47:46 +08:00
package com.njcn.auth.controller;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.njcn.auth.service.UserTokenService;
import com.njcn.common.pojo.constant.SecurityConstants;
import com.njcn.common.pojo.dto.UserTokenInfo;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.common.utils.LogUtil;
import com.njcn.common.utils.sm.DesUtils;
import com.njcn.redis.utils.RedisUtil;
import com.njcn.user.api.UserFeignClient;
import com.njcn.web.controller.BaseController;
import com.njcn.web.utils.RequestUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import java.security.KeyPair;
import java.security.Principal;
import java.security.interfaces.RSAPublicKey;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* @author hongawen
*/
@Api(tags = "认证中心")
@Slf4j
@RestController
@RequestMapping("/oauth")
@AllArgsConstructor
public class AuthController extends BaseController {
private final TokenEndpoint tokenEndpoint;
private final KeyPair keyPair;
private final RedisUtil redisUtil;
private final UserFeignClient userFeignClient;
private final UserTokenService userTokenService;
@ApiIgnore
@ApiOperation("登录认证")
@ApiImplicitParams({
@ApiImplicitParam(name = SecurityConstants.GRANT_TYPE, defaultValue = "password", value = "授权模式", required = true),
@ApiImplicitParam(name = SecurityConstants.CLIENT_ID, defaultValue = "njcn", value = "Oauth2客户端ID", required = true),
@ApiImplicitParam(name = SecurityConstants.CLIENT_SECRET, defaultValue = "njcnpqs", value = "Oauth2客户端秘钥", required = true),
@ApiImplicitParam(name = SecurityConstants.REFRESH_TOKEN, value = "刷新token"),
@ApiImplicitParam(name = SecurityConstants.USERNAME, value = "登录用户名"),
@ApiImplicitParam(name = SecurityConstants.PASSWORD, value = "登录密码"),
@ApiImplicitParam(name = SecurityConstants.IMAGE_CODE, value = "图形验证码"),
})
@PostMapping("/token")
public Object postAccessToken(@ApiIgnore Principal principal, @RequestParam @ApiIgnore Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
String methodDescribe = getMethodDescribe("postAccessToken");
String username = parameters.get(SecurityConstants.USERNAME);
String grantType = parameters.get(SecurityConstants.GRANT_TYPE);
//正式环境需删除,均是加密的用户名
if (!grantType.equalsIgnoreCase(SecurityConstants.PASSWORD)) {
username = DesUtils.aesDecrypt(username);
}
if (grantType.equalsIgnoreCase(SecurityConstants.REFRESH_TOKEN_KEY)) {
//如果是刷新token需要去黑名单校验
userTokenService.judgeRefreshToken(parameters.get(SecurityConstants.REFRESH_TOKEN_KEY));
}
RequestUtil.saveLoginName(username);
OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
//用户的登录名&密码校验成功后,判断当前该用户是否可以正常使用系统
userFeignClient.judgeUserStatus(username);
//登录成功后记录token信息并处理踢人效果
userTokenService.recordUserInfo(oAuth2AccessToken);
if (!grantType.equalsIgnoreCase(SecurityConstants.PASSWORD)) {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, oAuth2AccessToken, methodDescribe);
} else {
return oAuth2AccessToken;
}
}
@ApiOperation("用户登出系统")
@DeleteMapping("/logout")
public HttpResult<Object> logout() {
String methodDescribe = getMethodDescribe("logout");
String userIndex = RequestUtil.getUserIndex();
String username = RequestUtil.getUsername();
LogUtil.njcnDebug(log, "{},用户名为:{}", methodDescribe, username);
String blackUserKey = SecurityConstants.TOKEN_BLACKLIST_PREFIX + userIndex;
String onlineUserKey = SecurityConstants.TOKEN_ONLINE_PREFIX + userIndex;
Object onlineTokenInfoOld = redisUtil.getObjectByKey(onlineUserKey);
List<UserTokenInfo> blackUsers = (List<UserTokenInfo>) redisUtil.getObjectByKey(blackUserKey);
UserTokenInfo userTokenInfo;
if (!Objects.isNull(onlineTokenInfoOld)) {
//清除在线token信息
redisUtil.delete(onlineUserKey);
userTokenInfo = (UserTokenInfo) onlineTokenInfoOld;
if (CollectionUtils.isEmpty(blackUsers)) {
blackUsers = new ArrayList<>();
}
blackUsers.add(userTokenInfo);
LocalDateTime refreshTokenExpire = userTokenInfo.getRefreshTokenExpire();
long lifeTime = Math.abs(refreshTokenExpire.plusMinutes(5L).toEpochSecond(ZoneOffset.of("+8")) - LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")));
redisUtil.saveByKeyWithExpire(blackUserKey, blackUsers, lifeTime);
}
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
}
/**
* 文档隐藏该接口
*/
@ApiIgnore
@ApiOperation("RSA公钥获取接口")
@GetMapping("/getPublicKey")
public Map<String, Object> getPublicKey() {
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAKey key = new RSAKey.Builder(publicKey).build();
return new JWKSet(key).toJSONObject();
}
}