Commit 41635fed by tutingyin

refactor: 客户端登录认证适配PC

parent 4e65c777
package com.skr.mdm.authentication.user;
import com.skr.mdm.authentication.user.imei.ImeiAuthenticationException;
import com.skr.mdm.authentication.user.oaid.OaidAuthenticationException;
import com.skr.mdm.authentication.user.serial.SerialAuthenticationException;
import com.skr.mdm.authentication.user.qr.NumberLimitException;
import com.skr.mdm.authentication.user.uuid.UuidAuthenticationException;
import com.skr.mdm.enums.ResultCodeEnum;
import com.skr.mdm.result.ResponseResult;
import com.skr.mdm.util.ResponseUtil;
......@@ -28,15 +26,9 @@ public class UserAuthenticationFailureHandler implements AuthenticationFailureHa
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
ResponseResult result = ResponseResult.failure(ResultCodeEnum.LOGIN_FAILURE);
if (exception instanceof ImeiAuthenticationException) {
if (exception instanceof SerialAuthenticationException) {
result = ResponseResult.failure(ResultCodeEnum.IMEI_NONE);
}
if (exception instanceof OaidAuthenticationException) {
result = ResponseResult.failure(ResultCodeEnum.OAID_NONE);
}
if (exception instanceof UuidAuthenticationException) {
result = ResponseResult.failure(ResultCodeEnum.UUID_NONE);
}
if (exception instanceof NumberLimitException) {
result = ResponseResult.failure(ResultCodeEnum.NUMBER_OVER);
}
......@@ -48,4 +40,4 @@ public class UserAuthenticationFailureHandler implements AuthenticationFailureHa
}
}
\ No newline at end of file
package com.skr.mdm.authentication.user.imei;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.skr.mdm.bean.dto.UserLoginCallbackDTO;
import com.skr.mdm.dao.DeviceEquipmentDao;
import com.skr.mdm.dto.LoginUserDTO;
import com.skr.mdm.entity.DeviceEquipmentDO;
import com.skr.mdm.enums.DeleteStateEnum;
import com.skr.mdm.enums.EquipmentStateEnum;
import com.skr.mdm.rabbitmq.RabbitMQProvider;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
* @author nfq
* @date 2020/7/15 10:58
*/
@Service
public class ImeiUserDetailsServiceImpl implements UserDetailsService {
private static final String SPLIT = "-";
private Integer companyId;
@Autowired
private DeviceEquipmentDao equipmentDao;
@Autowired
private RabbitMQProvider rabbitMQProvider;
@Override
public UserDetails loadUserByUsername(String imei) throws UsernameNotFoundException {
if (StringUtils.isBlank(imei) || companyId == null) {
throw new ImeiAuthenticationException("imei为空:" + imei + "companyId:" + companyId);
}
String firstImei = imei;
String endImei = null;
if (imei.contains(SPLIT)) {
String[] split = StringUtils.split(firstImei, SPLIT);
firstImei = split[0];
endImei = split[1];
}
DeviceEquipmentDO deviceEquipmentDO = new LambdaQueryChainWrapper<>(equipmentDao)
.eq(DeviceEquipmentDO::getCompanyId, companyId)
.eq(DeviceEquipmentDO::getImei, firstImei)
.eq(DeviceEquipmentDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.one();
if (deviceEquipmentDO == null && StringUtils.isNotBlank(endImei)) {
deviceEquipmentDO = new LambdaQueryChainWrapper<>(equipmentDao)
.eq(DeviceEquipmentDO::getCompanyId, companyId)
.eq(DeviceEquipmentDO::getImei, endImei)
.eq(DeviceEquipmentDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.one();
}
if (deviceEquipmentDO == null) {
throw new ImeiAuthenticationException("imei不存在:" + imei + "companyId:" + companyId);
}
// 激活时间
if (EquipmentStateEnum.INACTIVATED.getState().equals(deviceEquipmentDO.getEquipmentState())) {
LambdaUpdateChainWrapper<DeviceEquipmentDO> updateChainWrapper = new LambdaUpdateChainWrapper<>(equipmentDao);
updateChainWrapper.set(DeviceEquipmentDO::getActivationTime, new Date())
.eq(DeviceEquipmentDO::getId, deviceEquipmentDO.getId())
.update();
// 异步拉取全局指令
UserLoginCallbackDTO userLoginCallbackDTO = UserLoginCallbackDTO.builder()
.deviceIdList(ListUtil.toList(deviceEquipmentDO.getId()))
.departmentId(deviceEquipmentDO.getDepartmentId())
.companyId(deviceEquipmentDO.getCompanyId())
.build();
rabbitMQProvider.publishRegisterEventWithDelayed(userLoginCallbackDTO);
}
LoginUserDTO loginUserDTO = new LoginUserDTO();
BeanUtils.copyProperties(deviceEquipmentDO, loginUserDTO);
return loginUserDTO;
}
public void setCompanyId(Integer companyId) {
this.companyId = companyId;
}
}
package com.skr.mdm.authentication.user.oaid;
import org.springframework.security.core.AuthenticationException;
/**
* @author nfq
* @date 2021/1/29 15:22
*/
public class OaidAuthenticationException extends AuthenticationException {
private static final long serialVersionUID = 7614868747227090707L;
public OaidAuthenticationException(String msg) {
super(msg);
}
}
package com.skr.mdm.authentication.user.oaid;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import cn.hutool.crypto.symmetric.SM4;
import com.skr.mdm.enums.MdmEncryptEnum;
import com.skr.mdm.util.SmUtils;
import io.swagger.models.HttpMethod;
import org.springframework.lang.Nullable;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author nfq
* @date 2021/1/29 15:05
*/
public class OaidAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public static final String SPRING_SECURITY_FORM_OAID_KEY = "oaid";
public static final String COMPANY_ID = "companyId";
public static final String SECRET_KEY = "secretKey";
private final String oaidParameter = SPRING_SECURITY_FORM_OAID_KEY;
private final String companyIdParameter = COMPANY_ID;
private final String secretKeyParameter = SECRET_KEY;
private final boolean postOnly = true;
private SM4 sm4 = null;
private String mdmEncrypt;
public OaidAuthenticationFilter() {
super(new AntPathRequestMatcher("/oaid/login", "POST"));
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
if (postOnly && !request.getMethod().equals(HttpMethod.POST.name())) {
throw new AuthenticationServiceException("Authentication method not supported:" + request.getMethod());
}
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
obtainSecretKey(request);
}
String oaid = obtainOaid(request);
String companyId = obtainCompanyId(request);
if (oaid == null) {
oaid = "";
}
oaid = oaid.trim();
OaidAuthenticationToken oaidAuthenticationToken = new OaidAuthenticationToken(oaid, companyId);
setDetails(request, oaidAuthenticationToken);
return this.getAuthenticationManager().authenticate(oaidAuthenticationToken);
}
@Nullable
protected String obtainOaid(HttpServletRequest request) {
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
return sm4.decryptStr(request.getParameter(oaidParameter));
}
return request.getParameter(oaidParameter);
}
@Nullable
protected String obtainCompanyId(HttpServletRequest request) {
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
return sm4.decryptStr(request.getParameter(companyIdParameter));
}
return request.getParameter(companyIdParameter);
}
@Nullable
protected String obtainSecretKey(HttpServletRequest request) {
String secretKey = request.getHeader(secretKeyParameter);
SM2 sm2 = SmUtils.sm2Sign();
byte[] secretKeyBytes = sm2.decrypt(secretKey, KeyType.PrivateKey);
sm4 = SmUtil.sm4(secretKeyBytes);
return request.getHeader(secretKeyParameter);
}
protected void setDetails(HttpServletRequest request, OaidAuthenticationToken oaidAuthenticationToken) {
oaidAuthenticationToken.setDetails(authenticationDetailsSource.buildDetails(request));
}
public void setMdmEncrypt(String mdmEncrypt) {
this.mdmEncrypt = mdmEncrypt;
}
}
package com.skr.mdm.authentication.user.oaid;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
/**
* @author nfq
* @date 2021/1/29 15:14
*/
public class OaidAuthenticationProvider implements AuthenticationProvider {
private OaidUserDetailsServiceImpl userDetailsService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
OaidAuthenticationToken authenticationToken = (OaidAuthenticationToken) authentication;
String principal = (String) authenticationToken.getPrincipal();
String companyId = (String) authenticationToken.getCompanyId();
userDetailsService.setCompanyId(Integer.valueOf(companyId));
// 校验oaid
UserDetails userDetails = userDetailsService.loadUserByUsername(principal);
if (userDetails == null) {
throw new OaidAuthenticationException(
"UserDetailsService returned null, which is an interface contract violation");
}
OaidAuthenticationToken authenticationResult = new OaidAuthenticationToken(userDetails.getAuthorities(), userDetails, companyId);
authenticationResult.setDetails(authentication.getDetails());
return authenticationResult;
}
@Override
public boolean supports(Class<?> authentication) {
return (OaidAuthenticationToken.class.isAssignableFrom(authentication));
}
public void setUserDetailsService(OaidUserDetailsServiceImpl userDetailsService) {
this.userDetailsService = userDetailsService;
}
}
package com.skr.mdm.authentication.user.oaid;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
/**
* @author nfq
* @date 2021/1/29 15:06
*/
public class OaidAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = 2637723175472434118L;
/**
* oaid
*/
private final Object principal;
private final Object companyId;
public OaidAuthenticationToken(Object principal, Object companyId) {
super(null);
this.principal = principal;
this.companyId = companyId;
setAuthenticated(false);
}
/**
* Creates a token with the supplied array of authorities.
*
* @param authorities the collection of <tt>GrantedAuthority</tt>s for the principal
* represented by this authentication object.
* @param principal
*/
public OaidAuthenticationToken(Collection<? extends GrantedAuthority> authorities, Object principal, Object companyId) {
super(authorities);
this.principal = principal;
this.companyId = companyId;
super.setAuthenticated(true);
}
@Override
public void setAuthenticated(boolean authenticated) {
super.setAuthenticated(authenticated);
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Object getPrincipal() {
return this.principal;
}
@Override
public void eraseCredentials() {
super.eraseCredentials();
}
public Object getCompanyId() {
return companyId;
}
}
package com.skr.mdm.authentication.user.oaid;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.skr.mdm.bean.dto.UserLoginCallbackDTO;
import com.skr.mdm.dao.DeviceEquipmentDao;
import com.skr.mdm.dto.LoginUserDTO;
import com.skr.mdm.entity.DeviceEquipmentDO;
import com.skr.mdm.enums.DeleteStateEnum;
import com.skr.mdm.enums.EquipmentStateEnum;
import com.skr.mdm.rabbitmq.RabbitMQProvider;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
* @author nfq
* @date 2021/1/29 15:15
*/
@Service
public class OaidUserDetailsServiceImpl implements UserDetailsService {
private Integer companyId;
@Autowired
private DeviceEquipmentDao equipmentDao;
@Autowired
private RabbitMQProvider rabbitMQProvider;
@Override
public UserDetails loadUserByUsername(String oaid) throws UsernameNotFoundException {
if (StringUtils.isBlank(oaid) || companyId == null) {
throw new OaidAuthenticationException("oaid为空:" + oaid + "companyId:" + companyId);
}
if (oaid.contains("0000000000")) {
throw new OaidAuthenticationException("非法的oaid:" + oaid);
}
DeviceEquipmentDO deviceEquipmentDO = new LambdaQueryChainWrapper<>(equipmentDao)
.eq(DeviceEquipmentDO::getOaid, oaid)
.eq(DeviceEquipmentDO::getCompanyId, companyId)
.eq(DeviceEquipmentDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.one();
if (deviceEquipmentDO == null) {
throw new OaidAuthenticationException("oaid不存在:" + oaid + "companyId:" + companyId);
}
// 激活时间
if (EquipmentStateEnum.INACTIVATED.getState().equals(deviceEquipmentDO.getEquipmentState())) {
LambdaUpdateChainWrapper<DeviceEquipmentDO> updateChainWrapper = new LambdaUpdateChainWrapper<>(equipmentDao);
updateChainWrapper
.set(DeviceEquipmentDO::getActivationTime, new Date())
.eq(DeviceEquipmentDO::getId, deviceEquipmentDO.getId())
.update();
// 异步拉取全局指令
UserLoginCallbackDTO userLoginCallbackDTO = UserLoginCallbackDTO.builder()
.deviceIdList(ListUtil.toList(deviceEquipmentDO.getId()))
.companyId(deviceEquipmentDO.getCompanyId())
.departmentId(deviceEquipmentDO.getDepartmentId())
.build();
rabbitMQProvider.publishRegisterEventWithDelayed(userLoginCallbackDTO);
}
LoginUserDTO loginUserDTO = new LoginUserDTO();
BeanUtils.copyProperties(deviceEquipmentDO, loginUserDTO);
return loginUserDTO;
}
public void setCompanyId(Integer companyId) {
this.companyId = companyId;
}
}
......@@ -27,9 +27,7 @@ public class UsernameAuthenticationFilter extends AbstractAuthenticationProcessi
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
public static final String IMEI = "imei";
public static final String OAID = "oaid";
public static final String UUID = "uuid";
public static final String SERIAL = "serial";
public static final String LOGIN_METHOD = "loginMethod";
public static final String COMPANY_ID = "companyId";
......@@ -38,9 +36,7 @@ public class UsernameAuthenticationFilter extends AbstractAuthenticationProcessi
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
private String imeiParameter = IMEI;
private final String oaidParameter = OAID;
private final String uuidParameter = UUID;
private String serialParameter = SERIAL;
private String loginMethodParameter = LOGIN_METHOD;
private final String companyIdParameter = COMPANY_ID;
private final String secretKeyParameter = SECRET_KEY;
......@@ -66,9 +62,7 @@ public class UsernameAuthenticationFilter extends AbstractAuthenticationProcessi
}
String username = obtainUsername(request);
String password = obtainPassword(request);
String imei = obtainImei(request);
String oaid = obtainOaid(request);
String uuid = obtainUuid(request);
String serialNumber = obtainSerialNumber(request);
String loginMethod = obtainLoginMethod(request);
String companyId = obtainCompanyId(request);
......@@ -80,16 +74,8 @@ public class UsernameAuthenticationFilter extends AbstractAuthenticationProcessi
password = "";
}
if (imei == null) {
imei = "";
}
if (oaid == null) {
oaid = "";
}
if (uuid == null) {
uuid = "";
if (serialNumber == null) {
serialNumber = "";
}
if (loginMethod == null) {
......@@ -101,7 +87,7 @@ public class UsernameAuthenticationFilter extends AbstractAuthenticationProcessi
}
username = username.trim();
UsernameAuthenticationToken authRequest = new UsernameAuthenticationToken(username, password, imei, oaid, uuid, loginMethod, companyId);
UsernameAuthenticationToken authRequest = new UsernameAuthenticationToken(username, password, serialNumber, loginMethod, companyId);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
......@@ -135,27 +121,11 @@ public class UsernameAuthenticationFilter extends AbstractAuthenticationProcessi
}
@Nullable
protected String obtainImei(HttpServletRequest request) {
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
return sm4.decryptStr(request.getParameter(imeiParameter));
}
return request.getParameter(imeiParameter);
}
@Nullable
protected String obtainOaid(HttpServletRequest request) {
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
return sm4.decryptStr(request.getParameter(oaidParameter));
}
return request.getParameter(oaidParameter);
}
@Nullable
protected String obtainUuid(HttpServletRequest request) {
protected String obtainSerialNumber(HttpServletRequest request) {
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
return sm4.decryptStr(request.getParameter(uuidParameter));
return sm4.decryptStr(request.getParameter(serialParameter));
}
return request.getParameter(uuidParameter);
return request.getParameter(serialParameter);
}
@Nullable
......@@ -182,4 +152,4 @@ public class UsernameAuthenticationFilter extends AbstractAuthenticationProcessi
public void setMdmEncrypt(String mdmEncrypt) {
this.mdmEncrypt = mdmEncrypt;
}
}
}
\ No newline at end of file
......@@ -59,9 +59,7 @@ public class UsernameAuthenticationProvider implements AuthenticationProvider {
.userName(equipmentDO.getUserName())
.departmentName(equipmentDO.getDepartmentName())
.companyName(companyDO.getCompanyName())
.imei(equipmentDO.getImei())
.oaid(equipmentDO.getOaid())
.uuid(equipmentDO.getUuid())
.serialNum(equipmentDO.getSerialNumber())
.build();
RegisterEquipmentUtil.registerGaodeTerminal(gaodeTerminalQO, equipmentDO);
}
......@@ -73,9 +71,7 @@ public class UsernameAuthenticationProvider implements AuthenticationProvider {
UsernameAuthenticationToken authenticationToken = (UsernameAuthenticationToken) authentication;
String principal = (String) authenticationToken.getPrincipal();
Object credentials = authenticationToken.getCredentials();
String imei = (String) authenticationToken.getImei();
String oaid = (String) authenticationToken.getOaid();
String uuid = (String) authenticationToken.getUuid();
String serialNumber = (String) authenticationToken.getSerialNum();
String loginMethod = (String) authenticationToken.getLoginMethod();
String companyId = (String) authenticationToken.getCompanyId();
......@@ -83,44 +79,15 @@ public class UsernameAuthenticationProvider implements AuthenticationProvider {
String loginType = "";
// 检查imei oaid UUID是否注册
DeviceEquipmentDO equipmentDO = null;
if (StringUtils.isNotBlank(imei)) {
loginType = "imei:" + imei;
String endImei = null;
if (imei.contains("-")) {
String[] split = StringUtils.split(imei, "-");
imei = split[0];
endImei = split[1];
}
equipmentDO = new LambdaQueryChainWrapper<>(equipmentDao)
.eq(DeviceEquipmentDO::getImei, imei)
.eq(DeviceEquipmentDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.eq(DeviceEquipmentDO::getCompanyId, Integer.valueOf(companyId))
.one();
if (equipmentDO == null && StringUtils.isNotBlank(endImei)) {
equipmentDO = new LambdaQueryChainWrapper<>(equipmentDao)
.eq(DeviceEquipmentDO::getCompanyId, companyId)
.eq(DeviceEquipmentDO::getImei, endImei)
.eq(DeviceEquipmentDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.one();
}
}
if (Objects.isNull(equipmentDO) && StringUtils.isNotBlank(oaid)) {
loginType = "oaid:" + oaid;
equipmentDO = new LambdaQueryChainWrapper<>(equipmentDao)
.eq(DeviceEquipmentDO::getOaid, oaid)
.eq(DeviceEquipmentDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.eq(DeviceEquipmentDO::getCompanyId, Integer.valueOf(companyId))
.one();
}
if (Objects.isNull(equipmentDO) && StringUtils.isNotBlank(uuid)) {
loginType = "uuid:" + uuid;
if (StringUtils.isNotBlank(serialNumber)) {
loginType = "serialNumber:" + serialNumber;
equipmentDO = new LambdaQueryChainWrapper<>(equipmentDao)
.eq(DeviceEquipmentDO::getUuid, uuid)
.eq(DeviceEquipmentDO::getSerialNumber, serialNumber)
.eq(DeviceEquipmentDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.eq(DeviceEquipmentDO::getCompanyId, Integer.valueOf(companyId))
.one();
}
// imei oaid uuid有一个唯一标识即可
// serialNum 唯一标识
if (equipmentDO == null) {
// 校验用户名
userDetailsService.setCompanyId(Integer.valueOf(companyId));
......@@ -149,9 +116,7 @@ public class UsernameAuthenticationProvider implements AuthenticationProvider {
equipmentDO.setDepartmentName(loginUserDTO.getDepartmentName());
equipmentDO.setCompanyId(loginUserDTO.getCompanyId());
equipmentDO.setEquipmentType(EquipmentTypeEnum.CELL_PHONE.getType());
equipmentDO.setImei(imei);
equipmentDO.setOaid(oaid);
equipmentDO.setUuid(uuid);
equipmentDO.setSerialNumber(serialNumber);
equipmentDO.setActivationTime(new Date());
String equipmentName = getEquipmentName(loginUserDTO.getUserId(), equipmentDO.getUserName(), Integer.valueOf(companyId));
equipmentDO.setEquipmentName(equipmentName);
......@@ -167,7 +132,7 @@ public class UsernameAuthenticationProvider implements AuthenticationProvider {
pushUserLoginEvent(equipmentDO, loginUserDTO);
}
UsernameAuthenticationToken authenticationResult = new UsernameAuthenticationToken(userDetails.getAuthorities(), userDetails, imei, oaid, uuid, companyId);
UsernameAuthenticationToken authenticationResult = new UsernameAuthenticationToken(userDetails.getAuthorities(), userDetails, serialNumber, companyId);
authenticationResult.setDetails(authentication.getDetails());
return authenticationResult;
}
......
......@@ -15,30 +15,24 @@ public class UsernameAuthenticationToken extends AbstractAuthenticationToken {
private final Object principal;
private Object credentials;
private final Object imei;
private final Object oaid;
private final Object uuid;
private final Object serialNum;
private Object loginMethod;
private final Object companyId;
public UsernameAuthenticationToken(Object principal, Object credentials, Object imei, Object oaid, Object uuid, Object loginMethod, Object companyId) {
public UsernameAuthenticationToken(Object principal, Object credentials, Object serialNum, Object loginMethod, Object companyId) {
super(null);
this.principal = principal;
this.credentials = credentials;
this.imei = imei;
this.oaid = oaid;
this.uuid = uuid;
this.serialNum = serialNum;
this.loginMethod = loginMethod;
this.companyId = companyId;
setAuthenticated(false);
}
public UsernameAuthenticationToken(Collection<? extends GrantedAuthority> authorities, Object principal, Object imei, Object oaid, Object uuid, Object companyId) {
public UsernameAuthenticationToken(Collection<? extends GrantedAuthority> authorities, Object principal, Object serialNum, Object companyId) {
super(authorities);
this.principal = principal;
this.imei = imei;
this.oaid = oaid;
this.uuid = uuid;
this.serialNum = serialNum;
this.companyId = companyId;
super.setAuthenticated(true);
}
......@@ -58,23 +52,15 @@ public class UsernameAuthenticationToken extends AbstractAuthenticationToken {
super.setAuthenticated(isAuthenticated);
}
public Object getImei() {
return this.imei;
public Object getSerialNum() {
return this.serialNum;
}
public Object getLoginMethod() {
return loginMethod;
}
public Object getOaid() {
return oaid;
}
public Object getUuid() {
return uuid;
}
public Object getCompanyId() {
return companyId;
}
}
}
\ No newline at end of file
......@@ -31,7 +31,7 @@ public class UsernameDetailsServiceImpl implements UserDetailsService {
throw new UsernameNotFoundException("username为空:" + username + "companyId:" + companyId);
}
AuUserDO userDO = new LambdaQueryChainWrapper<>(userDao)
.eq(AuUserDO::getPhoneNumber, username)
.eq(AuUserDO::getUserName, username)
.eq(AuUserDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.eq(AuUserDO::getCompanyId, companyId)
.one();
......@@ -50,4 +50,4 @@ public class UsernameDetailsServiceImpl implements UserDetailsService {
public void setCompanyId(Integer companyId) {
this.companyId = companyId;
}
}
}
\ No newline at end of file
package com.skr.mdm.authentication.user.imei;
package com.skr.mdm.authentication.user.serial;
import org.springframework.security.core.AuthenticationException;
......@@ -6,12 +6,12 @@ import org.springframework.security.core.AuthenticationException;
* @author nfq
* @date 2020/7/16 14:47
*/
public class ImeiAuthenticationException extends AuthenticationException {
public class SerialAuthenticationException extends AuthenticationException {
private static final long serialVersionUID = -3323794937564446615L;
public ImeiAuthenticationException(String msg) {
public SerialAuthenticationException(String msg) {
super(msg);
}
}
}
\ No newline at end of file
package com.skr.mdm.authentication.user.imei;
package com.skr.mdm.authentication.user.serial;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
......@@ -23,14 +23,14 @@ import java.io.IOException;
* @author nfq
* @date 2020/7/15 10:10
*/
public class ImeiAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public class SerialAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public static final String SPRING_SECURITY_FORM_IMEI_KEY = "imei";
public static final String SPRING_SECURITY_FORM_IMEI_KEY = "serialNum";
public static final String COMPANY_ID = "companyId";
public static final String SECRET_KEY = "secretKey";
private final String imeiParameter = SPRING_SECURITY_FORM_IMEI_KEY;
private final String serialNumParameter = SPRING_SECURITY_FORM_IMEI_KEY;
private final String companyIdParameter = COMPANY_ID;
private final String secretKeyParameter = SECRET_KEY;
......@@ -41,8 +41,8 @@ public class ImeiAuthenticationFilter extends AbstractAuthenticationProcessingFi
private String mdmEncrypt;
public ImeiAuthenticationFilter() {
super(new AntPathRequestMatcher("/imei/login", "POST"));
public SerialAuthenticationFilter() {
super(new AntPathRequestMatcher("/serial/login", "POST"));
}
@Override
......@@ -55,27 +55,27 @@ public class ImeiAuthenticationFilter extends AbstractAuthenticationProcessingFi
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
obtainSecretKey(request);
}
String imei = obtainImei(request);
String serialNumber = obtainImei(request);
String companyId = obtainCompanyId(request);
if (imei == null) {
imei = "";
if (serialNumber == null) {
serialNumber = "";
}
imei = imei.trim();
serialNumber = serialNumber.trim();
ImeiAuthenticationToken imeiAuthenticationToken = new ImeiAuthenticationToken(imei, companyId);
SerialAuthenticationToken serialAuthenticationToken = new SerialAuthenticationToken(serialNumber, companyId);
setDetails(request, imeiAuthenticationToken);
setDetails(request, serialAuthenticationToken);
return this.getAuthenticationManager().authenticate(imeiAuthenticationToken);
return this.getAuthenticationManager().authenticate(serialAuthenticationToken);
}
@Nullable
protected String obtainImei(HttpServletRequest request) {
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
return sm4.decryptStr(request.getParameter(imeiParameter));
return sm4.decryptStr(request.getParameter(serialNumParameter));
}
return request.getParameter(imeiParameter);
return request.getParameter(serialNumParameter);
}
@Nullable
......@@ -95,11 +95,11 @@ public class ImeiAuthenticationFilter extends AbstractAuthenticationProcessingFi
return request.getHeader(secretKeyParameter);
}
protected void setDetails(HttpServletRequest request, ImeiAuthenticationToken imeiAuthenticationToken) {
imeiAuthenticationToken.setDetails(authenticationDetailsSource.buildDetails(request));
protected void setDetails(HttpServletRequest request, SerialAuthenticationToken serialAuthenticationToken) {
serialAuthenticationToken.setDetails(authenticationDetailsSource.buildDetails(request));
}
public void setMdmEncrypt(String mdmEncrypt) {
this.mdmEncrypt = mdmEncrypt;
}
}
}
\ No newline at end of file
package com.skr.mdm.authentication.user.imei;
package com.skr.mdm.authentication.user.serial;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
......@@ -9,35 +9,35 @@ import org.springframework.security.core.userdetails.UserDetails;
* @author nfq
* @date 2020/7/15 10:39
*/
public class ImeiAuthenticationProvider implements AuthenticationProvider {
public class SerialAuthenticationProvider implements AuthenticationProvider {
private ImeiUserDetailsServiceImpl userDetailsService;
private SerialUserDetailsServiceImpl userDetailsService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
ImeiAuthenticationToken authenticationToken = (ImeiAuthenticationToken) authentication;
SerialAuthenticationToken authenticationToken = (SerialAuthenticationToken) authentication;
String principal = (String) authenticationToken.getPrincipal();
String companyId = (String) authenticationToken.getCompanyId();
userDetailsService.setCompanyId(Integer.valueOf(companyId));
// 校验imei
UserDetails userDetails = userDetailsService.loadUserByUsername(principal);
if (userDetails == null) {
throw new ImeiAuthenticationException(
throw new SerialAuthenticationException(
"UserDetailsService returned null, which is an interface contract violation");
}
ImeiAuthenticationToken authenticationResult = new ImeiAuthenticationToken(userDetails.getAuthorities(), userDetails, companyId);
SerialAuthenticationToken authenticationResult = new SerialAuthenticationToken(userDetails.getAuthorities(), userDetails, companyId);
authenticationResult.setDetails(authentication.getDetails());
return authenticationResult;
}
@Override
public boolean supports(Class<?> authentication) {
return (ImeiAuthenticationToken.class.isAssignableFrom(authentication));
return (SerialAuthenticationToken.class.isAssignableFrom(authentication));
}
public void setUserDetailsService(ImeiUserDetailsServiceImpl userDetailsService) {
public void setUserDetailsService(SerialUserDetailsServiceImpl userDetailsService) {
this.userDetailsService = userDetailsService;
}
}
}
\ No newline at end of file
package com.skr.mdm.authentication.user.imei;
package com.skr.mdm.authentication.user.serial;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
......@@ -9,7 +9,7 @@ import java.util.Collection;
* @author nfq
* @date 2020/7/15 10:12
*/
public class ImeiAuthenticationToken extends AbstractAuthenticationToken {
public class SerialAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = -8791155317019718470L;
/**
......@@ -18,7 +18,7 @@ public class ImeiAuthenticationToken extends AbstractAuthenticationToken {
private final Object principal;
private final Object companyId;
public ImeiAuthenticationToken(Object principal, Object companyId) {
public SerialAuthenticationToken(Object principal, Object companyId) {
super(null);
this.principal = principal;
this.companyId = companyId;
......@@ -32,7 +32,7 @@ public class ImeiAuthenticationToken extends AbstractAuthenticationToken {
* represented by this authentication object.
* @param principal
*/
public ImeiAuthenticationToken(Collection<? extends GrantedAuthority> authorities, Object principal, Object companyId) {
public SerialAuthenticationToken(Collection<? extends GrantedAuthority> authorities, Object principal, Object companyId) {
super(authorities);
this.principal = principal;
this.companyId = companyId;
......@@ -62,4 +62,4 @@ public class ImeiAuthenticationToken extends AbstractAuthenticationToken {
public Object getCompanyId() {
return companyId;
}
}
}
\ No newline at end of file
package com.skr.mdm.authentication.user.uuid;
package com.skr.mdm.authentication.user.serial;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
......@@ -22,10 +22,11 @@ import java.util.Date;
/**
* @author nfq
* @date 2021/1/29 15:15
* @date 2020/7/15 10:58
*/
@Service
public class UuidUserDetailsServiceImpl implements UserDetailsService {
public class SerialUserDetailsServiceImpl implements UserDetailsService {
private Integer companyId;
......@@ -35,40 +36,38 @@ public class UuidUserDetailsServiceImpl implements UserDetailsService {
private RabbitMQProvider rabbitMQProvider;
@Override
public UserDetails loadUserByUsername(String uuid) throws UsernameNotFoundException {
if (StringUtils.isBlank(uuid) || companyId == null) {
throw new UuidAuthenticationException("uuid为空:" + uuid + "companyId:" + companyId);
public UserDetails loadUserByUsername(String serialNum) throws UsernameNotFoundException {
if (StringUtils.isBlank(serialNum) || companyId == null) {
throw new SerialAuthenticationException("序列号为空:" + serialNum + "companyId:" + companyId);
}
DeviceEquipmentDO deviceEquipmentDO = new LambdaQueryChainWrapper<>(equipmentDao)
.eq(DeviceEquipmentDO::getUuid, uuid)
.eq(DeviceEquipmentDO::getCompanyId, companyId)
.eq(DeviceEquipmentDO::getSerialNumber, serialNum)
.eq(DeviceEquipmentDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.one();
if (deviceEquipmentDO == null) {
throw new UuidAuthenticationException("uuid不存在:" + uuid + "companyId:" + companyId);
throw new SerialAuthenticationException("序列号不存在:" + serialNum + "companyId:" + companyId);
}
// 激活时间
if (EquipmentStateEnum.INACTIVATED.getState().equals(deviceEquipmentDO.getEquipmentState())) {
LambdaUpdateChainWrapper<DeviceEquipmentDO> updateChainWrapper = new LambdaUpdateChainWrapper<>(equipmentDao);
updateChainWrapper
.set(DeviceEquipmentDO::getActivationTime, new Date())
updateChainWrapper.set(DeviceEquipmentDO::getActivationTime, new Date())
.eq(DeviceEquipmentDO::getId, deviceEquipmentDO.getId())
.update();
// 异步拉取全局指令
UserLoginCallbackDTO userLoginCallbackDTO = UserLoginCallbackDTO.builder()
.deviceIdList(ListUtil.toList(deviceEquipmentDO.getId()))
.companyId(deviceEquipmentDO.getCompanyId())
.departmentId(deviceEquipmentDO.getDepartmentId())
.companyId(deviceEquipmentDO.getCompanyId())
.build();
rabbitMQProvider.publishRegisterEventWithDelayed(userLoginCallbackDTO);
}
LoginUserDTO loginUserDTO = new LoginUserDTO();
BeanUtils.copyProperties(deviceEquipmentDO, loginUserDTO);
return loginUserDTO;
}
public void setCompanyId(Integer companyId) {
this.companyId = companyId;
}
}
}
\ No newline at end of file
package com.skr.mdm.authentication.user.sms;
import org.springframework.security.core.AuthenticationException;
public class SMSCodeLoginException extends AuthenticationException {
private static final long serialVersionUID = 6731162291714457528L;
public SMSCodeLoginException(String msg) {
super(msg);
}
}
\ No newline at end of file
package com.skr.mdm.authentication.user.sms;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import cn.hutool.crypto.symmetric.SM4;
import com.skr.mdm.enums.MdmEncryptEnum;
import com.skr.mdm.util.SmUtils;
import org.springframework.http.HttpMethod;
import org.springframework.lang.Nullable;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SmsAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public static final String SPRING_SECURITY_FORM_SMS_CODE_KEY = "SMSCode";
public static final String PHONE = "phone";
public static final String COMPANY_ID = "companyId";
public static final String IMEI = "imei";
public static final String OAID = "oaid";
public static final String UUID = "uuid";
public static final String SECRET_KEY = "secretKey";
private SM4 sm4 = null;
private String mdmEncrypt;
public SmsAuthenticationFilter() {
super(new AntPathRequestMatcher("/sms/login", HttpMethod.POST.name()));
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
if (Boolean.TRUE && !request.getMethod().equals(HttpMethod.POST.name())) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
}
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
obtainSecretKey(request);
}
String smsCode = obtainSmsCode(request);
String phone = obtainPhone(request);
String imei = obtainImei(request);
String oaid = obtainOaid(request);
String uuid = obtainUuid(request);
String companyId = obtainCompanyId(request);
if (phone == null) {
phone = "";
}
if (smsCode == null) {
smsCode = "";
}
if (imei == null) {
imei = "";
}
if (oaid == null) {
oaid = "";
}
if (uuid == null) {
uuid = "";
}
SmsAuthenticationToken authRequest = new SmsAuthenticationToken(phone, smsCode, imei, oaid, uuid, companyId);
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
@Nullable
protected String obtainSmsCode(HttpServletRequest request) {
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
return sm4.decryptStr(request.getParameter(SPRING_SECURITY_FORM_SMS_CODE_KEY));
}
return request.getParameter(SPRING_SECURITY_FORM_SMS_CODE_KEY);
}
@Nullable
protected String obtainPhone(HttpServletRequest request) {
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
return sm4.decryptStr(request.getParameter(PHONE));
}
return request.getParameter(PHONE);
}
@Nullable
protected String obtainCompanyId(HttpServletRequest request) {
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
return sm4.decryptStr(request.getParameter(COMPANY_ID));
}
return request.getParameter(COMPANY_ID);
}
@Nullable
protected String obtainImei(HttpServletRequest request) {
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
return sm4.decryptStr(request.getParameter(IMEI));
}
return request.getParameter(IMEI);
}
@Nullable
protected String obtainOaid(HttpServletRequest request) {
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
return sm4.decryptStr(request.getParameter(OAID));
}
return request.getParameter(OAID);
}
@Nullable
protected String obtainUuid(HttpServletRequest request) {
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
return sm4.decryptStr(request.getParameter(UUID));
}
return request.getParameter(UUID);
}
@Nullable
protected String obtainSecretKey(HttpServletRequest request) {
String secretKey = request.getHeader(SECRET_KEY);
SM2 sm2 = SmUtils.sm2Sign();
byte[] secretKeyBytes = sm2.decrypt(secretKey, KeyType.PrivateKey);
sm4 = SmUtil.sm4(secretKeyBytes);
return request.getHeader(SECRET_KEY);
}
protected void setDetails(HttpServletRequest request,
SmsAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
public void setMdmEncrypt(String mdmEncrypt) {
this.mdmEncrypt = mdmEncrypt;
}
}
\ No newline at end of file
package com.skr.mdm.authentication.user.sms;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.skr.mdm.authentication.user.qr.NumberLimitException;
import com.skr.mdm.bean.dto.UserLoginCallbackDTO;
import com.skr.mdm.bean.qo.GaodeTerminalQO;
import com.skr.mdm.dao.AuCompanyDao;
import com.skr.mdm.dao.DeviceEquipmentDao;
import com.skr.mdm.dto.LoginUserDTO;
import com.skr.mdm.entity.AuCompanyDO;
import com.skr.mdm.entity.DeviceEquipmentDO;
import com.skr.mdm.enums.DeleteStateEnum;
import com.skr.mdm.enums.EquipmentTypeEnum;
import com.skr.mdm.rabbitmq.RabbitMQProvider;
import com.skr.mdm.util.RegisterEquipmentUtil;
import com.skr.mdm.util.SmUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import javax.net.ssl.*;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@Slf4j
public class SmsAuthenticationProvider implements AuthenticationProvider {
private static final Integer COUNT_EQUIPMENT = 9;
private SmsDetailsServiceImpl userDetailsService;
private DeviceEquipmentDao equipmentDao;
private AuCompanyDao companyDao;
private RabbitMQProvider rabbitMQProvider;
private final String MOB_TECH_URL = "https://webapi.sms.mob.com/sms/verify";
private final String MOB_TECH_APP_KEY = "appkey=36269a90b7fe4";
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
SmsAuthenticationToken authenticationToken = (SmsAuthenticationToken) authentication;
String phone = (String) authenticationToken.getPrincipal();
Object smsCode = authenticationToken.getCredentials();
String imei = (String) authenticationToken.getImei();
String oaid = (String) authenticationToken.getOaid();
String uuid = (String) authenticationToken.getUuid();
String companyId = (String) authenticationToken.getCompanyId();
// mob teach 短信验证
String codeCheck = requestData(MOB_TECH_URL, MOB_TECH_APP_KEY + "&phone=" + phone + "&zone=86" + "&code=" + smsCode);
if (!StringUtils.equalsIgnoreCase(codeCheck, HttpURLConnection.HTTP_OK + "")) {
throw new SMSCodeLoginException(codeCheck);
}
UserDetails userDetails = null;
DeviceEquipmentDO equipmentDO = null;
String loginType = "imei";
if (StringUtils.isNotBlank(imei)) {
LambdaQueryChainWrapper<DeviceEquipmentDO> queryChainWrapper = new LambdaQueryChainWrapper<>(equipmentDao);
equipmentDO = queryChainWrapper
.eq(DeviceEquipmentDO::getImei, imei)
.eq(DeviceEquipmentDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.eq(DeviceEquipmentDO::getCompanyId, Integer.valueOf(companyId))
.one();
}
if (Objects.isNull(equipmentDO) && StringUtils.isNotBlank(oaid)) {
loginType = "oaid";
equipmentDO = new LambdaQueryChainWrapper<>(equipmentDao)
.eq(DeviceEquipmentDO::getOaid, oaid)
.eq(DeviceEquipmentDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.eq(DeviceEquipmentDO::getCompanyId, Integer.valueOf(companyId))
.one();
}
if (Objects.isNull(equipmentDO) && StringUtils.isNotBlank(uuid)) {
loginType = "uuid";
equipmentDO = new LambdaQueryChainWrapper<>(equipmentDao)
.eq(DeviceEquipmentDO::getUuid, uuid)
.eq(DeviceEquipmentDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.eq(DeviceEquipmentDO::getCompanyId, Integer.valueOf(companyId))
.one();
}
// imei oaid uuid 有一个唯一标识即可
// 校验用户名
userDetailsService.setCompanyId(Integer.valueOf(companyId));
userDetails = userDetailsService.loadUserByUsername(phone);
if (userDetails == null) {
throw new InternalAuthenticationServiceException(
"UserDetailsService returned null");
}
LoginUserDTO loginUserDTO = (LoginUserDTO) userDetails;
if (Objects.nonNull(equipmentDO) && !equipmentDO.getUserId().equals(loginUserDTO.getUserId())) {
throw new InternalAuthenticationServiceException(
"UserDetailsService returned null, which is an interface contract violation " + loginType + " already exist!");
} else if (Objects.isNull(equipmentDO)) {
// 注册设备
equipmentDO = new DeviceEquipmentDO();
equipmentDO.setUserId(loginUserDTO.getUserId());
equipmentDO.setUserName(loginUserDTO.getUserName());
equipmentDO.setDepartmentId(loginUserDTO.getDepartmentId());
equipmentDO.setDepartmentName(loginUserDTO.getDepartmentName());
equipmentDO.setCompanyId(loginUserDTO.getCompanyId());
equipmentDO.setEquipmentType(EquipmentTypeEnum.CELL_PHONE.getType());
equipmentDO.setImei(imei);
equipmentDO.setOaid(oaid);
equipmentDO.setUuid(uuid);
equipmentDO.setActivationTime(new Date());
String equipmentName = getEquipmentName(equipmentDO.getUserName(), Integer.valueOf(companyId));
equipmentDO.setEquipmentName(equipmentName);
AuCompanyDO companyDO = companyDao.selectById(loginUserDTO.getCompanyId());
// 设备数量限制
String allowUseNumber = companyDO.getAllowUseNumber();
SM2 sm2 = SmUtils.sm2();
String authorizationNumber = StrUtil.utf8Str(sm2.decryptFromBcd(allowUseNumber, KeyType.PrivateKey));
Long equipmentCount = new LambdaQueryChainWrapper<>(equipmentDao)
.eq(DeviceEquipmentDO::getCompanyId, loginUserDTO.getCompanyId())
.eq(DeviceEquipmentDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.count();
if (equipmentCount >= Integer.parseInt(authorizationNumber)) {
throw new NumberLimitException("设备数量超出限制,无法注册,请联系管理员!");
}
// 创建猎鹰终端
if (companyDO.getSid() != null) {
GaodeTerminalQO gaodeTerminalQO = GaodeTerminalQO.builder()
.sid(companyDO.getSid())
.phoneNumber(loginUserDTO.getPhoneNumber())
.equipmentName(equipmentDO.getEquipmentName())
.userName(equipmentDO.getUserName())
.departmentName(equipmentDO.getDepartmentName())
.companyName(companyDO.getCompanyName())
.imei(equipmentDO.getImei())
.oaid(equipmentDO.getOaid())
.uuid(equipmentDO.getUuid())
.build();
RegisterEquipmentUtil.registerGaodeTerminal(gaodeTerminalQO, equipmentDO);
}
equipmentDao.insert(equipmentDO);
BeanUtils.copyProperties(equipmentDO, loginUserDTO);
loginUserDTO.setId(equipmentDO.getId());
// 异步拉取全局指令
UserLoginCallbackDTO userLoginCallbackDTO = UserLoginCallbackDTO.builder().deviceIdList(ListUtil.toList(equipmentDO.getId())).companyId(loginUserDTO.getCompanyId()).build();
rabbitMQProvider.publishRegisterEventWithDelayed(userLoginCallbackDTO);
} else {
// 退出登录 再次登录直接响应
BeanUtils.copyProperties(equipmentDO, loginUserDTO);
}
SmsAuthenticationToken authenticationResult = new SmsAuthenticationToken(userDetails.getAuthorities(), userDetails, imei, oaid, uuid, companyId);
authenticationResult.setDetails(authentication.getDetails());
return authenticationResult;
}
private String getEquipmentName(String userName, Integer companyId) {
List<DeviceEquipmentDO> equipmentDOList = new LambdaQueryChainWrapper<>(equipmentDao)
.likeRight(DeviceEquipmentDO::getEquipmentName, EquipmentTypeEnum.CELL_PHONE.getName())
.eq(DeviceEquipmentDO::getUserName, userName)
.eq(DeviceEquipmentDO::getCompanyId, companyId)
.eq(DeviceEquipmentDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.list();
if (CollectionUtils.isEmpty(equipmentDOList)) {
return EquipmentTypeEnum.CELL_PHONE.getName() + "01";
}
List<Integer> numberList = new ArrayList<>(equipmentDOList.size());
equipmentDOList.forEach(equipmentDO -> {
if (equipmentDO.getEquipmentName().length() == 4) {
String number = StringUtils.substringAfter(equipmentDO.getEquipmentName(), EquipmentTypeEnum.CELL_PHONE.getName());
if (StringUtils.isNumeric(number)) {
numberList.add(Integer.valueOf(number));
}
}
});
if (CollectionUtils.isEmpty(numberList)) {
return EquipmentTypeEnum.CELL_PHONE.getName() + "01";
}
Integer max = CollectionUtil.max(numberList);
if (max < COUNT_EQUIPMENT) {
max++;
return EquipmentTypeEnum.CELL_PHONE.getName() + "0" + max;
}
max++;
return EquipmentTypeEnum.CELL_PHONE.getName() + max;
}
@Override
public boolean supports(Class<?> authentication) {
return (SmsAuthenticationToken.class.isAssignableFrom(authentication));
}
public void setUserDetailsService(SmsDetailsServiceImpl userDetailsService) {
this.userDetailsService = userDetailsService;
}
public void setEquipmentDao(DeviceEquipmentDao equipmentDao) {
this.equipmentDao = equipmentDao;
}
public void setCompanyDao(AuCompanyDao companyDao) {
this.companyDao = companyDao;
}
public void setRabbitMQProvider(RabbitMQProvider rabbitMQProvider) {
this.rabbitMQProvider = rabbitMQProvider;
}
/**
* 发起https 请求
*
* @param address
* @param params
* @return
*/
public static String requestData(String address, String params) {
HttpURLConnection conn = null;
try {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
//ip host verify
HostnameVerifier hv = new HostnameVerifier() {
@Override
public boolean verify(String urlHostName, SSLSession session) {
return urlHostName.equals(session.getPeerHost());
}
};
//set ip host verify
HttpsURLConnection.setDefaultHostnameVerifier(hv);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
URL url = new URL(address);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");// POST
conn.setConnectTimeout(3000);
conn.setReadTimeout(3000);
// set params ;post params
if (params != null) {
conn.setDoOutput(true);
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.write(params.getBytes(StandardCharsets.UTF_8));
out.flush();
out.close();
}
conn.connect();
//get result
// 200 验证成功
// 405 AppKey为空
// 406 AppKey无效
// 456 国家代码或手机号码为空
// 457 手机号码格式错误
// 466 请求校验的验证码为空
// 467 请求校验验证码频繁(5分钟内同一个appkey
// 的同一个号码最多只能校验三次)
// 468 验证码错误
// 474 没有打开服务端验证开关
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
return parsRtn(conn.getInputStream());
} else {
log.warn("验证码校验失败: 编码 {} 报文{}", conn.getResponseCode() + "", conn.getResponseMessage());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
}
return null;
}
/**
* 将从服务器获得的流is转换为字符串
*
* @param is
* @return
* @throws IOException
*/
private static String parsRtn(InputStream is) throws IOException {
//初始值,起标志位作用
int len = -1;
//缓冲区
byte[] buf = new byte[128];
//捕获内存缓冲区的数据转换为字节数组
ByteArrayOutputStream bas = new ByteArrayOutputStream();
//循环读取内容,将输入流的内容放进缓冲区中
while ((len = is.read(buf)) != -1) {
//将缓冲区内容写进输出流,0是从起始偏移量,len是指定的字符个数
bas.write(buf, 0, len);
}
//最终结果,将字节数组转换成字符
return JSONUtil.parseObj(bas.toString()).get("status") + "";
}
}
\ No newline at end of file
package com.skr.mdm.authentication.user.sms;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
public class SmsAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = -3578288222289154241L;
private final Object principal;
private Object credentials;
private final Object imei;
private final Object oaid;
private final Object uuid;
private final Object companyId;
public SmsAuthenticationToken(Object principal, Object credentials, Object imei, Object oaid, Object uuid,Object companyId) {
super(null);
this.principal = principal;
this.credentials = credentials;
this.imei = imei;
this.oaid = oaid;
this.uuid = uuid;
this.companyId = companyId;
setAuthenticated(false);
}
public SmsAuthenticationToken(Collection<? extends GrantedAuthority> authorities, Object principal, Object imei, Object oaid, Object uuid, Object companyId) {
super(authorities);
this.principal = principal;
this.imei = imei;
this.oaid = oaid;
this.uuid = uuid;
this.companyId = companyId;
super.setAuthenticated(true);
}
@Override
public Object getCredentials() {
return this.credentials;
}
@Override
public Object getPrincipal() {
return this.principal;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
super.setAuthenticated(isAuthenticated);
}
public Object getImei() {
return this.imei;
}
public Object getOaid() {
return oaid;
}
public Object getUuid() {
return uuid;
}
public Object getCompanyId() {
return companyId;
}
}
\ No newline at end of file
package com.skr.mdm.authentication.user.sms;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.skr.mdm.dao.AuUserDao;
import com.skr.mdm.dto.LoginUserDTO;
import com.skr.mdm.entity.AuUserDO;
import com.skr.mdm.enums.DeleteStateEnum;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class SmsDetailsServiceImpl implements UserDetailsService {
private Integer companyId;
@Autowired
private AuUserDao auUserDao;
@Override
public UserDetails loadUserByUsername(String phone) throws UsernameNotFoundException {
if (companyId == null) {
throw new UsernameNotFoundException("companyId为null:" + companyId);
}
LambdaQueryWrapper<AuUserDO> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper
.eq(AuUserDO::getPhoneNumber, phone)
.eq(AuUserDO::getIsDelete, DeleteStateEnum.NON_DELETE.getState())
.eq(AuUserDO::getCompanyId, companyId);
AuUserDO userDO = auUserDao.selectOne(lambdaQueryWrapper);
if (userDO == null) {
throw new UsernameNotFoundException("用户手机号不存在:" + phone + "companyId:" + companyId);
}
LoginUserDTO loginUserDTO = new LoginUserDTO();
BeanUtils.copyProperties(userDO, loginUserDTO);
loginUserDTO.setUserId(userDO.getId());
loginUserDTO.setDepartmentId(userDO.getDepartmentId());
loginUserDTO.setDepartmentName(userDO.getDepartmentName());
loginUserDTO.setPassword(userDO.getPassword());
return loginUserDTO;
}
public void setCompanyId(Integer companyId) {
this.companyId = companyId;
}
}
\ No newline at end of file
package com.skr.mdm.authentication.user.uuid;
import org.springframework.security.core.AuthenticationException;
/**
* @author nfq
* @date 2021/1/29 15:22
*/
public class UuidAuthenticationException extends AuthenticationException {
private static final long serialVersionUID = -5602561092590320699L;
public UuidAuthenticationException(String msg) {
super(msg);
}
}
package com.skr.mdm.authentication.user.uuid;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import cn.hutool.crypto.symmetric.SM4;
import com.skr.mdm.enums.MdmEncryptEnum;
import com.skr.mdm.util.SmUtils;
import io.swagger.models.HttpMethod;
import org.springframework.lang.Nullable;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author nfq
* @date 2021/1/29 15:05
*/
public class UuidAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public static final String SPRING_SECURITY_FORM_UUID_KEY = "uuid";
public static final String COMPANY_ID = "companyId";
public static final String SECRET_KEY = "secretKey";
private final String uuidParameter = SPRING_SECURITY_FORM_UUID_KEY;
private final String companyIdParameter = COMPANY_ID;
private final String secretKeyParameter = SECRET_KEY;
private final boolean postOnly = true;
private SM4 sm4 = null;
private String mdmEncrypt;
public UuidAuthenticationFilter() {
super(new AntPathRequestMatcher("/uuid/login", "POST"));
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
if (postOnly && !request.getMethod().equals(HttpMethod.POST.name())) {
throw new AuthenticationServiceException("Authentication method not supported:" + request.getMethod());
}
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
obtainSecretKey(request);
}
String uuid = obtainUuid(request);
String companyId = obtainCompanyId(request);
if (uuid == null) {
uuid = "";
}
uuid = uuid.trim();
UuidAuthenticationToken oaidAuthenticationToken = new UuidAuthenticationToken(uuid, companyId);
setDetails(request, oaidAuthenticationToken);
return this.getAuthenticationManager().authenticate(oaidAuthenticationToken);
}
@Nullable
protected String obtainUuid(HttpServletRequest request) {
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
return sm4.decryptStr(request.getParameter(uuidParameter));
}
return request.getParameter(uuidParameter);
}
@Nullable
protected String obtainCompanyId(HttpServletRequest request) {
if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
return sm4.decryptStr(request.getParameter(companyIdParameter));
}
return request.getParameter(companyIdParameter);
}
@Nullable
protected String obtainSecretKey(HttpServletRequest request) {
String secretKey = request.getHeader(secretKeyParameter);
SM2 sm2 = SmUtils.sm2Sign();
byte[] secretKeyBytes = sm2.decrypt(secretKey, KeyType.PrivateKey);
sm4 = SmUtil.sm4(secretKeyBytes);
return request.getHeader(secretKeyParameter);
}
protected void setDetails(HttpServletRequest request, UuidAuthenticationToken oaidAuthenticationToken) {
oaidAuthenticationToken.setDetails(authenticationDetailsSource.buildDetails(request));
}
public void setMdmEncrypt(String mdmEncrypt) {
this.mdmEncrypt = mdmEncrypt;
}
}
package com.skr.mdm.authentication.user.uuid;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
/**
* @author nfq
* @date 2021/1/29 15:14
*/
public class UuidAuthenticationProvider implements AuthenticationProvider {
private UuidUserDetailsServiceImpl userDetailsService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
UuidAuthenticationToken authenticationToken = (UuidAuthenticationToken) authentication;
String principal = (String) authenticationToken.getPrincipal();
String companyId = (String) authenticationToken.getCompanyId();
userDetailsService.setCompanyId(Integer.valueOf(companyId));
// 校验uuid
UserDetails userDetails = userDetailsService.loadUserByUsername(principal);
if (userDetails == null) {
throw new UuidAuthenticationException(
"UserDetailsService returned null, which is an interface contract violation");
}
UuidAuthenticationToken authenticationResult = new UuidAuthenticationToken(userDetails.getAuthorities(), userDetails, companyId);
authenticationResult.setDetails(authentication.getDetails());
return authenticationResult;
}
@Override
public boolean supports(Class<?> authentication) {
return (UuidAuthenticationToken.class.isAssignableFrom(authentication));
}
public void setUserDetailsService(UuidUserDetailsServiceImpl userDetailsService) {
this.userDetailsService = userDetailsService;
}
}
package com.skr.mdm.authentication.user.uuid;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
/**
* @author nfq
* @date 2021/1/29 15:06
*/
public class UuidAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = -7421570826625845499L;
/**
* uuid
*/
private final Object principal;
private final Object companyId;
public UuidAuthenticationToken(Object principal, Object companyId) {
super(null);
this.principal = principal;
this.companyId = companyId;
setAuthenticated(false);
}
/**
* Creates a token with the supplied array of authorities.
*
* @param authorities the collection of <tt>GrantedAuthority</tt>s for the principal
* represented by this authentication object.
* @param principal
*/
public UuidAuthenticationToken(Collection<? extends GrantedAuthority> authorities, Object principal, Object companyId) {
super(authorities);
this.principal = principal;
this.companyId = companyId;
super.setAuthenticated(true);
}
@Override
public void setAuthenticated(boolean authenticated) {
super.setAuthenticated(authenticated);
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Object getPrincipal() {
return this.principal;
}
@Override
public void eraseCredentials() {
super.eraseCredentials();
}
public Object getCompanyId() {
return companyId;
}
}
......@@ -30,7 +30,7 @@ public class AntiReplayUtil {
private final String nonceParameter = RequestHeaderConstants.REQUEST_HEADER_NONCE;
private final String timestampHeaderParameter = RequestHeaderConstants.REQUEST_HEADER_TIMESTAMP;
private final String signParameter = RequestHeaderConstants.REQUEST_HEADER_SIGN;
private final String androidParameter = RequestHeaderConstants.REQUEST_HEADER_USER_AGENT;
private final String pcParameter = RequestHeaderConstants.REQUEST_HEADER_USER_AGENT;
private final String csrfToken = RequestHeaderConstants.REQUEST_HEADER_CSRF_TOKEN;
@Value("${request.expire.seconds}")
private Long requestExpire;
......@@ -53,15 +53,15 @@ public class AntiReplayUtil {
String nonce = request.getHeader(this.nonceParameter);
String timestampParameter = request.getHeader(this.timestampHeaderParameter);
String sign = request.getHeader(this.signParameter);
String android = request.getHeader(this.androidParameter);
String pc = request.getHeader(this.pcParameter);
boolean checkParam = StringUtils.isBlank(nonce) || StringUtils.isBlank(timestampParameter) ||
StringUtils.isBlank(sign) || StringUtils.isBlank(android);
StringUtils.isBlank(sign) || StringUtils.isBlank(pc);
if (checkParam) {
log.warn("请求头内容不完整 timestampParameter:{} sign:{} nonce:{}, android:{} 请求地址:{}", timestampParameter, sign, nonce, android, request.getRequestURI());
log.warn("请求头内容不完整 timestampParameter:{} sign:{} nonce:{}, pc:{} 请求地址:{}", timestampParameter, sign, nonce, pc, request.getRequestURI());
throw new IllegalUserRequestException();
}
if (!StringUtils.equalsIgnoreCase("android", android)) {
log.warn("非安卓请求:{} 请求地址:{}", android, request.getRequestURI());
if (!StringUtils.equalsIgnoreCase("pc", pc)) {
log.warn("非安卓请求:{} 请求地址:{}", pc, request.getRequestURI());
throw new IllegalUserRequestException();
}
......@@ -153,4 +153,4 @@ public class AntiReplayUtil {
// 随机值放入缓存
redisUtils.set(RedisGetKeyUtil.getAdminQuestNonceKey(nonce), nonce, requestExpire);
}
}
}
\ No newline at end of file
......@@ -23,7 +23,7 @@ public class RegisterEquipmentUtil {
/**
* 生成设备名
*
* @param equipmentDOList 用户下的设备集合
* @param equipmentNameList 用户下的设备集合
* @param userName 用户名
* @return 设备名
*/
......@@ -75,4 +75,4 @@ public class RegisterEquipmentUtil {
equipmentDO.setTrid(trid);
return equipmentDO;
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment