package com.vci.ubcs.code.service.impl; import com.alibaba.fastjson.JSON; import com.vci.ubcs.code.config.HeaderMapRequestWrapper; import com.vci.ubcs.code.entity.TokenUserObject; import com.vci.ubcs.code.service.IPasswordFreeLoginService; import com.vci.ubcs.code.util.HttpUtils; import org.springblade.core.cache.utils.CacheUtil; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.redis.cache.BladeRedis; import org.springblade.core.tool.utils.Func; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import javax.annotation.Resource; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.List; /** * 免密登录服务 * @author ludc * @date 2023/9/11 15:45 */ @Service public class PasswordFreeLoginServiceImpl implements IPasswordFreeLoginService { // 通过服务注册中心获取网关的端口号 @Autowired private DiscoveryClient discoveryClient; @Value("${user-info.pwd-free-tenant-id}") private String pwdFreeTenantId; @Autowired private BladeRedis bladeRedis; // 缓存名 public static final String PWD_FREE_LOGIN_TOKEN = "pwdFreeLogin:Token:"; /** * 获取网关端口 * @return */ private String getGatewayPort() { List instances = discoveryClient.getInstances("ubcs-gateway"); if (!instances.isEmpty()) { ServiceInstance gatewayInstance = instances.get(0); return String.valueOf(gatewayInstance.getPort()); } return "80"; } /** * 免密登录并存入缓存,配合过滤器写法 * @param username 账号 * @return */ @Override public String passwordFreeLogin(String username, ServletRequest servletRequest) { // 免密登录接口地址 String loginUrl = "http://localhost:"+this.getGatewayPort()+"/ubcs-auth/oauth/token"; // 请求来自己哪个ip地址 HttpServletRequest request = (HeaderMapRequestWrapper) servletRequest; String ipAddr = request.getRemoteAddr(); // 先尝试从缓存当中取,如果不存在就登录 String redisToken = (String)bladeRedis.get(PWD_FREE_LOGIN_TOKEN+ipAddr); if(Func.isNotBlank(redisToken)){ // 缓存中已经存在就直接删除该缓存,主要为了避免统一ip下存在多个token的情况 bladeRedis.del(PWD_FREE_LOGIN_TOKEN+ipAddr); } // 不存在就重新获取token // 设置请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); headers.set("Authorization", "Basic c3dvcmQ6c3dvcmRfc2VjcmV0"); headers.set("Tenant-Id", pwdFreeTenantId); //设置请求体参数 MultiValueMap parameters = new LinkedMultiValueMap(); parameters.add("username",username); parameters.add("grant_type", "passwordfree"); parameters.add("scope", "all"); parameters.add("type", "account"); // 发送POST请求 String responseBody = HttpUtils.post(loginUrl, parameters,headers); //拿到响应体其中包含token,用request中的ip地址作为键值,将token存入缓存 TokenUserObject tokenUserObject = null; try { tokenUserObject = JSON.parseObject(responseBody, TokenUserObject.class); }catch (Exception e){ throw new ServiceException("responseBody转换TokenUserObject失败:"+e.getMessage()); } // 将token存入缓存当中,过期时间为24小时 bladeRedis.setEx(PWD_FREE_LOGIN_TOKEN+ipAddr,"bearer "+tokenUserObject.getAccess_token(),60*60*60*24L); return responseBody; } /** * 免密登录,改变当前webservice请求的header * @param username 账号 * @return */ @Override public boolean passwordFreeLogin2(String username, HttpServletRequest servletRequest) { // 免密登录接口地址 String loginUrl = "http://localhost:"+this.getGatewayPort()+"/ubcs-auth/oauth/token"; // 获取token,先设置请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); headers.set("Authorization", "Basic c3dvcmQ6c3dvcmRfc2VjcmV0"); headers.set("Tenant-Id", pwdFreeTenantId); //设置请求体参数 MultiValueMap parameters = new LinkedMultiValueMap(); parameters.add("username",username); parameters.add("grant_type", "passwordfree"); parameters.add("scope", "all"); parameters.add("type", "account"); // 发送POST请求 String responseBody = HttpUtils.post(loginUrl, parameters,headers); //拿到响应体其中包含token,用request中的ip地址作为键值,将token存入缓存 TokenUserObject tokenUserObject = null; try { tokenUserObject = JSON.parseObject(responseBody, TokenUserObject.class); }catch (Exception e){ throw new ServiceException("responseBody转换TokenUserObject失败:"+e.getMessage()); } HttpServletRequest request = (HeaderMapRequestWrapper) servletRequest; HeaderMapRequestWrapper requestWrapper = new HeaderMapRequestWrapper(request); //设置当前web接口的请求头 String token = "bearer " + tokenUserObject.getAccess_token(); // 将token设置到header中 requestWrapper.setHeader("Blade-Auth", token); requestWrapper.setHeader("Authorization","Basic c3dvcmQ6c3dvcmRfc2VjcmV0"); // 将token存入缓存当中,过期时间为24小时 return true; } }