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

com.github.yiuman.citrus.security.authenticate.AuthenticateProcessorImpl Maven / Gradle / Ivy

package com.github.yiuman.citrus.security.authenticate;

import com.github.yiuman.citrus.security.jwt.JwtToken;
import com.github.yiuman.citrus.security.jwt.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 认证处理器实现
 *
 * @author yiuman
 * @date 2020/4/3
 */
@Service
@Slf4j
public class AuthenticateProcessorImpl implements AuthenticateProcessor {

    /**
     * 认证模式参数KEY
     */
    private final static String AUTHENTICATION_MODE_PARAMETER_KEY = "mode";

    /**
     * 认证服务类
     */
    private final List authenticateServices;

    public AuthenticateProcessorImpl(List authenticateServices) {
        Assert.notNull(authenticateServices, "AuthenticateService must not be null");
        this.authenticateServices = authenticateServices;
    }

    @Override
    public AuthenticateService findByMode(String mode) throws AuthenticationException {
        if (StringUtils.isEmpty(mode)) {
            throw new AuthenticationServiceException("The Authenticate's parameter 'model' must not be null");
        }

        //找到对应模式的认证服务类
        return authenticateServices.parallelStream()
                .filter(authenticateService -> mode.equals(authenticateService.supportMode()))
                .findFirst()
                .orElseThrow(() ->
                        new AuthenticationServiceException(String.format("Cannot found Authenticate's model of %s", mode)));
    }


    @Override
    public Authentication authenticate(HttpServletRequest request) throws AuthenticationException {
        return findByMode(request.getParameter(AUTHENTICATION_MODE_PARAMETER_KEY)).authenticate(request);
    }

    @Override
    public JwtToken token(HttpServletRequest request) {
        HttpServletRequest actualRequest = request;
        if (!(request instanceof AbstractMultipartHttpServletRequest)) {
            try {
                //此处非Multipart就构造一个Json的RequestWrapper 用与适配多种请求方式
                actualRequest = new JsonServletRequestWrapper(request);
            } catch (Exception e) {
                throw new AuthenticationServiceException("BAD REQUEST");
            }
        }

        Map claims = new HashMap<>(16);
        claims.put(AUTHENTICATION_MODE_PARAMETER_KEY, actualRequest.getParameter(AUTHENTICATION_MODE_PARAMETER_KEY));
        Authentication authenticate = authenticate(actualRequest);
        return JwtUtils.generateToken((String) authenticate.getCredentials(), claims);
    }

    @Override
    public Optional resolve(HttpServletRequest request) {
        String token = JwtUtils.resolveToken(request);
        if (StringUtils.hasText(token) && JwtUtils.validateToken(token)) {
            Claims claims = JwtUtils.getClaims(token);
            String mode = (String) claims.get(AUTHENTICATION_MODE_PARAMETER_KEY);
            String identity = (String) claims.get(JwtUtils.getIdentityKey());
            try {
                AuthenticateService service = findByMode(mode);
                return service.resolve(token, identity);
            } catch (Exception e) {
                return Optional.empty();
            }

        }
        return Optional.empty();
    }

    @Override
    public void logout(HttpServletRequest request) {
        String token = JwtUtils.resolveToken(request);
        if (StringUtils.hasText(token) && JwtUtils.validateToken(token)) {
            Claims claims = JwtUtils.getClaims(token);
            String mode = (String) claims.get(AUTHENTICATION_MODE_PARAMETER_KEY);
            String identity = (String) claims.get(JwtUtils.getIdentityKey());
            try {
                AuthenticateService service = findByMode(mode);
                Optional authentication = service.resolve(token, identity);
                authentication.ifPresent(service::logout);
            } catch (Exception e) {
                log.error("logout exception", e);
            }

        }

    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy