zhuo
2025-03-15 257507122150b6105a0b9fd9c022015493063c99
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
@@ -1,7 +1,31 @@
package com.ruoyi.framework.web.service;
import javax.annotation.Resource;
import javax.net.ssl.SSLContext;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.config.SsoBean;
import com.ruoyi.common.core.domain.entity.User;
import com.ruoyi.framework.model.SsoOauthTokenModel;
import com.ruoyi.framework.model.SsoUserInfoModel;
import com.ruoyi.system.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -29,12 +53,24 @@
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
 * 登录校验方法
 *
 *
 * @author ruoyi
 */
@Component
@Slf4j
public class SysLoginService
{
    @Autowired
@@ -45,16 +81,25 @@
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ISysUserService userService;
    private ISysUserService sysUserService;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private SsoBean ssoBean;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    /**
     * 登录验证
     *
     *
     * @param username 用户名
     * @param password 密码
     * @param code 验证码
@@ -102,7 +147,7 @@
    /**
     * 校验验证码
     *
     *
     * @param username 用户名
     * @param code 验证码
     * @param uuid 唯一标识
@@ -176,6 +221,127 @@
        sysUser.setUserId(userId);
        sysUser.setLoginIp(IpUtils.getIpAddr());
        sysUser.setLoginDate(DateUtils.getNowDate());
        userService.updateUserProfile(sysUser);
        sysUserService.updateUserProfile(sysUser);
    }
    /**
     * 单点登录
     * @param code
     * @return
     */
    public String loginBySSO(String code) {
        // 获取单点登录token
        SsoOauthTokenModel tokenModel = this.getSsoAccessToken(code);
        if (tokenModel == null) {
            return null;
        }
        // 获取单点登录用户信息
        SsoUserInfoModel userInfo = this.getSsoUserInfo(tokenModel.getAccess_token());
        if (userInfo == null) {
            return null;
        }
        // 查询本地用户信息
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(userInfo.getEmployeeId(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.single.login.success")));
        redisTemplate.opsForValue().set("ssoOauthToken:idToken:" + userInfo.getEmployeeId(), tokenModel.getId_token(), 3, TimeUnit.DAYS);
        // 生成token
        return tokenService.createToken(null);
    }
    /**
     * **** 获取单点登录token ****
     * @param code
     * @return
     */
    public SsoOauthTokenModel getSsoAccessToken(String code) {
        List<NameValuePair> list = new LinkedList<>();
        list.add(new BasicNameValuePair("grant_type", "authorization_code"));
        list.add(new BasicNameValuePair("code", code));
        list.add(new BasicNameValuePair("client_id", ssoBean.getClientId()));
        list.add(new BasicNameValuePair("client_secret", ssoBean.getClientSecret()));
        list.add(new BasicNameValuePair("redirect_uri", ssoBean.getCallbackUrl()));
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/x-www-form-urlencoded");
        headers.put("Accept", "application/json");
        String result = doPost(ssoBean.getUrl() + "/oauth2/token", headers, list);
        if (org.apache.commons.lang3.StringUtils.isBlank(result)) {
            return null;
        }
        return JSON.parseObject(result, SsoOauthTokenModel.class);
    }
    /**
     * ***获取单点登录用户信息***
     * @param accessToken
     * @return
     */
    public SsoUserInfoModel getSsoUserInfo(String accessToken) {
        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", "Bearer " + accessToken);
        String result = doPost(ssoBean.getUrl() + "/userinfo", headers, null);
        if (org.apache.commons.lang3.StringUtils.isBlank(result)) {
            return null;
        }
        return JSON.parseObject(result, SsoUserInfoModel.class);
    }
    public static String doPost(String url, Map<String, String> headers, List<NameValuePair> params) {
        CloseableHttpClient client = createSSLClientDefault();
        CloseableHttpResponse response = null;
        try {
            HttpPost method = new HttpPost(url);
            headers.forEach(method::setHeader);
            if (params != null) {
                method.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            }
            response = client.execute(method);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                return EntityUtils.toString(entity);
            }
        } catch (Exception e) {
            log.error("统一登录请求出现异常", e.getMessage());
        } finally {
            try {
                if (client != null) {
                    client.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (Exception e) {
                log.error("统一登录请求出现异常", e.getMessage());
            }
        }
        return null;
    }
    private static CloseableHttpClient createSSLClientDefault() {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                //信任所有
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();
    }
}