浏览代码

扫描登录

liujunchi 2 年之前
父节点
当前提交
5b2a24dfcc

+ 1 - 1
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/config/WebMvcConfig.java

@@ -38,7 +38,7 @@ public class WebMvcConfig implements WebMvcConfigurer {
 	public void addInterceptors(InterceptorRegistry registry) {
 		registry.addInterceptor(tenantInterceptor).addPathPatterns("/**").
 				excludePathPatterns("/queryUserInfo","/user/updatePassword","/user/queryUserByPhone","/user/add",
-						"user/queryUserById/*","/role/queryRoleCodeListByUserId","/user/updateSysUser");
+						"user/queryUserById/*","/role/queryRoleCodeListByUserId","/user/updateSysUser","/user/open/*");
 		registry.addInterceptor(operationLogInterceptor).addPathPatterns("/userDevice/unbind").excludePathPatterns("/*");
 	}
 	

+ 9 - 3
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/config/WebSecurityConfig.java

@@ -1,5 +1,6 @@
 package com.ym.mec.auth.config;
 
+import com.ym.mec.common.redis.service.RedisCache;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -47,7 +48,11 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 	
 	@Autowired
 	private SysUserDeviceService sysUserDeviceService;
-	
+
+
+	@Autowired
+	private RedisCache<String,Object> redisCache;
+
 	@Override
 	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 		auth.authenticationProvider(daoAuthenticationProvider());
@@ -65,7 +70,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 			.addFilterBefore(getPhoneLoginAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
 				// 请求授权
 				.authorizeRequests()// 不需要权限认证的url
-				.antMatchers("/usernameLogin","/smsLogin", "/refreshToken", "/v2/api-docs").permitAll()// 任何请求
+				.antMatchers("/usernameLogin","/smsLogin", "/refreshToken", "/v2/api-docs","/user/open/*").permitAll()// 任何请求
 				.anyRequest()// 需要身份认证
 				.authenticated().and()// 关闭跨站请求防护
 				.csrf().disable();
@@ -74,7 +79,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 	@Override
 	public void configure(WebSecurity web) throws Exception {
 		web.ignoring().antMatchers("/usernameLogin", "/smsLogin", "/refreshToken",
-				"/v2/api-docs","/loginIn","/user/updatePassword");
+				"/v2/api-docs","/loginIn","/user/updatePassword","/user/open/*");
 	}
 
 	@Bean
@@ -105,6 +110,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
     	PhoneAuthenticationProvider provider = new PhoneAuthenticationProvider();
         // 设置userDetailsService
         provider.setUserDetailsService(defaultUserDetailsService);
+		provider.setRedisCache(redisCache);
         provider.setSmsCodeService(smsCodeService);
         provider.setSysUserService(sysUserService);
         provider.setSysUserDeviceService(sysUserDeviceService);

+ 35 - 6
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/core/provider/PhoneAuthenticationProvider.java

@@ -2,7 +2,10 @@ package com.ym.mec.auth.core.provider;
 
 import java.util.Date;
 
+import com.ym.mec.auth.web.controller.queryInfo.QRLoginDto;
+import com.ym.mec.common.redis.service.RedisCache;
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.InternalAuthenticationServiceException;
 import org.springframework.security.authentication.LockedException;
@@ -30,7 +33,9 @@ public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider
 	private SysUserService sysUserService;
 	
 	private SysUserDeviceService sysUserDeviceService;
-	
+
+	private RedisCache<String,Object> redisCache;
+
 	@Override
 	protected void additionalAuthenticationChecks(UserDetails userDetails, Authentication authentication) throws AuthenticationException {
 
@@ -48,19 +53,38 @@ public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider
 		}
 		String smsCode = loginEntity.getSmsCode();
 		String phone = loginEntity.getPhone();
+		String clientId = loginEntity.getClientId();
 
 		// 验证码验证
-		if (!smsCodeService.verifyValidCode(phone, smsCode)) {
+		if (!clientId.startsWith("QR_") && !smsCodeService.verifyValidCode(phone, smsCode)) {
 			throw new BadCredentialsException("验证码校验失败");
 		}
 
-		String clientId = loginEntity.getClientId();
 
 		Boolean isRegister = loginEntity.getIsRegister();
 		
 		String deviceNum = loginEntity.getDeviceNum();
 
-		SysUserInfo userInfo = sysUserService.queryUserInfoByPhone(phone);
+
+
+		SysUserInfo userInfo;
+
+		if (clientId.startsWith("QR_")) {
+			Object data = redisCache.get(loginEntity.getPhone());
+			if (data == null) {
+				throw new LockedException("用户不存在");
+			} else {
+				QRLoginDto loginDto = (QRLoginDto) data;
+				if (loginDto.getPrivateKey().equals(loginEntity.getSmsCode())) {
+					userInfo = loginDto.getUserInfo();
+					username = username.replaceAll(loginDto.getCode(),userInfo.getSysUser().getPhone());
+				} else {
+					throw new LockedException("用户不存在");
+				}
+			}
+		} else {
+			userInfo = sysUserService.queryUserInfoByPhone(phone);
+		}
 
 		if (userInfo == null) {
 			if (isRegister == false || StringUtils.equals("SYSTEM", clientId)) {
@@ -85,8 +109,9 @@ public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider
 			if (StringUtils.isNotBlank(deviceNum)) {
 				sysUserDeviceService.bindDevice(clientId, user.getId(), deviceNum, userInfo.getSysUser().getTenantId());
 			}
-			
-			if (!userInfo.getSysUser().getUserType().contains(clientId)) {
+
+			if (clientId.startsWith("QR_" )) {
+			} else  if (!userInfo.getSysUser().getUserType().contains(clientId)) {
 				if (isRegister == false || StringUtils.equals("SYSTEM", clientId)) {
 					throw new LockedException("用户不存在");
 				} else {
@@ -137,6 +162,10 @@ public class PhoneAuthenticationProvider extends AbstractAuthenticationProvider
 		this.userDetailsService = userDetailsService;
 	}
 
+	public void setRedisCache(RedisCache<String, Object> redisCache) {
+		this.redisCache = redisCache;
+	}
+
 	public void setSysUserService(SysUserService sysUserService) {
 		this.sysUserService = sysUserService;
 	}

+ 112 - 0
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/web/controller/UserController.java

@@ -1,17 +1,22 @@
 package com.ym.mec.auth.web.controller;
 
+import com.alibaba.fastjson.JSONObject;
+import com.huifu.adapay.core.util.StringUtil;
+import com.ym.mec.auth.api.dto.SysUserInfo;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.auth.service.SysRoleService;
 import com.ym.mec.auth.service.SysUserRoleService;
 import com.ym.mec.auth.service.SysUserService;
 import com.ym.mec.auth.service.TenantInfoService;
 import com.ym.mec.auth.api.dto.SysUserQueryInfo;
+import com.ym.mec.auth.web.controller.queryInfo.QRLoginDto;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.entity.ImResult;
 import com.ym.mec.common.entity.ImUserModel;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.QueryInfo;
+import com.ym.mec.common.redis.service.RedisCache;
 import com.ym.mec.common.security.AuthUser;
 import com.ym.mec.common.security.SecurityConstants;
 import com.ym.mec.common.security.SecurityUtils;
@@ -24,16 +29,28 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
 import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.web.bind.annotation.*;
 
+import java.io.IOException;
+import java.util.Base64;
+import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
 
 @RestController()
 @RequestMapping("user")
@@ -52,6 +69,10 @@ public class UserController extends BaseController {
 	private IdGeneratorService smsCodeService;
 	@Autowired
 	private TenantInfoService tenantInfoService;
+
+	@Autowired
+	private RedisCache<String,Object> redisCache;
+
 	@Value("${message.debugMode}")
 	private boolean debugMode;
 	@Autowired
@@ -377,4 +398,95 @@ public class UserController extends BaseController {
 	public HttpResponseResult<List<SysUser>> page(@RequestBody SysUserQueryInfo queryInfo) {
 		return succeed(sysUserService.queryEmployeeList(queryInfo));
 	}
+
+
+
+	@GetMapping("/open/getQRLoginCode")
+	@ApiOperation(value = "获取二维码登录code(不需要鉴权)")
+	public HttpResponseResult<String> getQRLoginCode(String clientId) {
+
+		String uuid = UUID.randomUUID().toString();
+
+		QRLoginDto qrLoginDto = new QRLoginDto();
+		qrLoginDto.setCode(uuid);
+		qrLoginDto.setClientId(clientId);
+		redisCache.put(uuid,qrLoginDto,50*60);
+		return succeed(uuid);
+	}
+
+
+	@GetMapping("/open/pollingQRLoginCode")
+	@ApiOperation(value = "前端轮询登录(不需要鉴权)")
+	public HttpResponseResult<QRLoginDto> pollingQRLoginCode(@ApiParam(value = "二维码登录code", required = true) @RequestParam("code") String code) {
+		if (StringUtil.isEmpty(code)) {
+			throw new BizException("登录失败");
+		}
+
+		Object obj = redisCache.get(code);
+		if (null != obj) {
+			QRLoginDto dto = (QRLoginDto) obj;
+			dto.setUserInfo(null);
+			return succeed(dto);
+		} else {
+			QRLoginDto qrLoginDto = new QRLoginDto();
+			qrLoginDto.setExpireFlag(true);
+			return succeed(qrLoginDto);
+		}
+	}
+
+	@GetMapping(value = "/qrLogin")
+	@ApiOperation(value = "二维码登录-扫码")
+	public HttpResponseResult<QRLoginDto> qrLogin(
+		@ApiParam(value = "二维码登录code", required = true) @RequestParam("code") String code
+	) throws IOException {
+		AuthUser authUser = SecurityUtils.getUser();
+		if (authUser == null) {
+			throw new BizException("请先登录");
+		}
+		SysUser sysUser = sysUserService.get(authUser.getUserId());
+
+
+		Object data = redisCache.get(code);
+		if (null == data) {
+			QRLoginDto qrLoginDto = new QRLoginDto();
+			qrLoginDto.setExpireFlag(true);
+			return succeed(qrLoginDto);
+		}
+		redisCache.put(code,data,50*60);
+		return succeed( (QRLoginDto) data);
+	}
+
+	@GetMapping(value = "/doQrLogin")
+	@ApiOperation(value = "二维码登录-确认登录")
+	public HttpResponseResult<QRLoginDto> doQrLogin(
+		@ApiParam(value = "二维码登录code", required = true) @RequestParam("code") String code
+	) {
+		AuthUser authUser = SecurityUtils.getUser();
+		if (authUser == null) {
+			throw new BizException("请先登录");
+		}
+		SysUser sysUser = sysUserService.get(authUser.getUserId());
+
+		Object data = redisCache.get(code);
+		if (null == data) {
+			QRLoginDto qrLoginDto = new QRLoginDto();
+			qrLoginDto.setExpireFlag(true);
+			return succeed(qrLoginDto);
+		}
+
+
+		SysUserInfo userInfo = sysUserService.queryUserInfoByPhone(sysUser.getPhone());
+		QRLoginDto dto = (QRLoginDto) data;
+		dto.setUserInfo(userInfo);
+
+
+		String uuid = UUID.randomUUID().toString();
+		dto.setPrivateKey(uuid);
+		redisCache.put(code,dto,50*60);
+
+		dto.setUserInfo(null);
+
+		return succeed(dto);
+	}
+
 }

+ 67 - 0
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/web/controller/queryInfo/QRLoginDto.java

@@ -0,0 +1,67 @@
+package com.ym.mec.auth.web.controller.queryInfo;
+
+import com.ym.mec.auth.api.dto.SysUserInfo;
+
+import java.io.Serializable;
+
+/**
+ * Description
+ *
+ * @author liujunchi
+ * @date 2023-02-24
+ */
+public class QRLoginDto implements Serializable {
+
+    // 是否过期
+    private Boolean expireFlag;
+
+    // clientId
+    private String clientId;
+
+    // code
+    private String code;
+
+    private String privateKey;
+
+    private SysUserInfo userInfo;
+
+    public String getPrivateKey() {
+        return privateKey;
+    }
+
+    public void setPrivateKey(String privateKey) {
+        this.privateKey = privateKey;
+    }
+
+    public SysUserInfo getUserInfo() {
+        return userInfo;
+    }
+
+    public void setUserInfo(SysUserInfo userInfo) {
+        this.userInfo = userInfo;
+    }
+
+    public Boolean getExpireFlag() {
+        return expireFlag;
+    }
+
+    public void setExpireFlag(Boolean expireFlag) {
+        this.expireFlag = expireFlag;
+    }
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+}