All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.bootx.platform.starter.auth.endpoint.TokenService Maven / Gradle / Ivy

There is a newer version: 1.3.6.2
Show newest version
package cn.bootx.platform.starter.auth.endpoint;

import cn.bootx.platform.starter.auth.authentication.AbstractAuthentication;
import cn.bootx.platform.starter.auth.authentication.GetAuthClientService;
import cn.bootx.platform.starter.auth.authentication.GetAuthLoginTypeService;
import cn.bootx.platform.starter.auth.configuration.AuthProperties;
import cn.bootx.platform.starter.auth.exception.ClientNotEnableException;
import cn.bootx.platform.starter.auth.exception.LoginFailureException;
import cn.bootx.platform.common.core.code.CommonCode;
import cn.bootx.platform.common.core.entity.UserDetail;
import cn.bootx.platform.common.core.util.CollUtil;
import cn.bootx.platform.starter.auth.entity.AuthClient;
import cn.bootx.platform.starter.auth.entity.AuthInfoResult;
import cn.bootx.platform.starter.auth.entity.AuthLoginType;
import cn.bootx.platform.starter.auth.entity.LoginAuthContext;
import cn.bootx.platform.starter.auth.handler.LoginFailureHandler;
import cn.bootx.platform.starter.auth.handler.LoginSuccessHandler;
import cn.bootx.platform.starter.auth.util.SecurityUtil;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * 认证相关服务
 *
 * @author xxm
 * @since 2021/7/30
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TokenService {

    private final GetAuthLoginTypeService getAuthLoginTypeService;

    private final GetAuthClientService getAuthClientService;

    private final AuthProperties authProperties;

    private final List abstractAuthentications;

    private final List loginSuccessHandlers;

    private final List loginFailureHandlers;

    /**
     * 登录
     */
    public String login(HttpServletRequest request, HttpServletResponse response) {
        AuthInfoResult authInfoResult;
        AuthLoginType authLoginType = this.getAuthLoginType(request);
        AuthClient authClient = this.getAuthApplication(request);
        try {
            LoginAuthContext loginAuthContext = new LoginAuthContext().setRequest(request)
                .setResponse(response)
                .setAuthProperties(authProperties)
                .setAuthLoginType(authLoginType)
                .setAuthClient(authClient);
            // 校验登录终端
            this.validateAuthClient(loginAuthContext);
            // 认证并获取结果
            authInfoResult = this.authentication(loginAuthContext);
            // 登录处理
            this.login(authInfoResult, loginAuthContext);
        }
        catch (LoginFailureException e) {
            // 登录失败回调
            this.loginFailureHandler(request, response, e);
            throw e;
        }
        // 登录成功回调
        this.loginSuccessHandler(request, response, authInfoResult);
        return StpUtil.getTokenValue();
    }

    /**
     * 成功处理
     */
    private void loginSuccessHandler(HttpServletRequest request, HttpServletResponse response,
            AuthInfoResult authInfoResult) {
        for (LoginSuccessHandler loginSuccessHandler : loginSuccessHandlers) {
            try {
                loginSuccessHandler.onLoginSuccess(request, response, authInfoResult);
            }
            catch (Exception ignored) {
            }
        }
    }

    /**
     * 失败处理
     */
    private void loginFailureHandler(HttpServletRequest request, HttpServletResponse response,
            LoginFailureException e) {
        for (LoginFailureHandler loginFailureHandler : loginFailureHandlers) {
            try {
                loginFailureHandler.onLoginFailure(request, response, e);
            }
            catch (Exception ignored) {
            }
        }
    }

    /**
     * 获取方式
     */
    private AuthLoginType getAuthLoginType(HttpServletRequest request) {
        // 登录方式
        AuthLoginType authLoginType = getAuthLoginTypeService.getAuthLoginType(SecurityUtil.getLoginType(request));
        if (!authLoginType.isEnable()) {
            throw new ClientNotEnableException();
        }
        return authLoginType;
    }

    /**
     * 获取终端
     */
    private AuthClient getAuthApplication(HttpServletRequest request) {
        // 终端
        AuthClient authClient = getAuthClientService.getAuthApplication(SecurityUtil.getClient(request));
        if (!authClient.isEnable()) {
            throw new ClientNotEnableException();
        }
        return authClient;
    }

    /**
     * 校验该认证应用是否支持此种登录方式
     */
    private void validateAuthClient(LoginAuthContext loginAuthContext) {
        AuthClient authClient = loginAuthContext.getAuthClient();
        AuthLoginType authLoginType = loginAuthContext.getAuthLoginType();
        if (CollUtil.isEmpty(authClient.getLoginTypeIds())
                || !authClient.getLoginTypeIds().contains(authLoginType.getId())) {
            throw new LoginFailureException("不支持的登录方式");
        }
    }

    /**
     * 认证
     */
    private @NotNull AuthInfoResult authentication(LoginAuthContext context) {
        String loginType = context.getAuthLoginType().getCode();
        return abstractAuthentications.stream()
            .filter(o -> o.adaptation(loginType))
            .findFirst()
            .map(o -> o.authentication(context))
            .orElseThrow(() -> new LoginFailureException("未找到对应的登录认证器"));
    }

    /**
     * 登录
     */
    private void login(AuthInfoResult authInfoResult, LoginAuthContext context) {
        AuthLoginType authLoginType = context.getAuthLoginType();
        AuthClient authClient = context.getAuthClient();
        SaLoginModel saLoginModel = new SaLoginModel().setDevice(authClient.getCode())
            .setTimeout(authLoginType.getTimeout() * 60);

        authInfoResult.setClient(authClient.getCode()).setLoginType(authLoginType.getCode());
        StpUtil.login(authInfoResult.getId(), saLoginModel);
        SaSession session = StpUtil.getSession();
        UserDetail userDetail = authInfoResult.getUserDetail();
        session.set(CommonCode.USER, userDetail);
    }

    /**
     * 退出
     */
    public void logout() {
        StpUtil.logout();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy