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

com.flyfish.oauth.common.auth.OAuthAuthenticator Maven / Gradle / Ivy

package com.flyfish.oauth.common.auth;

import com.flyfish.oauth.common.OAuth2PostAware;
import com.flyfish.oauth.common.OAuthFilterContext;
import com.flyfish.oauth.domain.OAuth2AccessToken;
import com.flyfish.oauth.domain.OAuthSSOToken;
import com.flyfish.oauth.domain.raw.SSOUserInfo;
import com.flyfish.oauth.utils.OAuthRequestParser;
import com.flyfish.oauth.utils.UserConvertUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * 开放认证器
 *
 * @author wangyu
 * 逻辑抽离,便于调用
 */
public class OAuthAuthenticator extends OAuth2PostAware {

    // 过滤的资源路径
    private static final List RESOURCE_TYPES =
            Arrays.asList(".js", ".css", ".ico", ".jpg", ".png", ".svg", ".gif", ".eot", ".ttf", ".woff");

    public static OAuthAuthenticator getInstance() {
        return SingletonHolder.INSTANCE;
    }

    /**
     * 检查请求状态
     *
     * @param request 请求
     * @return 结果
     */
    public boolean checkStatus(HttpServletRequest request) {
        // 如果是资源文件,或者是跳过的,直接放行,提高性能
        return !checkResource(request.getRequestURI()) || checkAllowed(request.getRequestURI(), client.getProperties().getAllowUris());
    }

    /**
     * 鉴权,这里使用请求上下文鉴权
     *
     * @param context 上下文
     * @return 通过与否
     */
    public AuthStatus authenticate(OAuthFilterContext context) throws IOException {
        HttpServletRequest request = context.getRequest();
        HttpServletResponse response = context.getResponse();
        // 解析请求
        OAuthRequestParser parsed = OAuthRequestParser.parse(request);
        // 获取token
        String accessToken = parsed.getAccessToken();
        // 检查放行规则,如果是认证请求,这里直接放行
        if (parsed.isAuthRequest()) {
            return AuthStatus.SKIP;
        }
        // 判断token有效性
        boolean tokenValid = accessToken != null && authenticationEntryPoint.checkAccessToken(accessToken);
        // 放行,并获取数据
        if (tokenValid) {
            if (authenticateSuccess(request, accessToken)) {
                return AuthStatus.SUCCESS;
            }
            return AuthStatus.REDIRECT;
        } else {
            String refreshToken = parsed.getRefreshToken();
            // 刷新token
            if (refreshAccessToken(response, refreshToken)) {
                authenticateSuccess(request, accessToken);
                return AuthStatus.SUCCESS;
            } else if (parsed.needRedirect() || client.getProperties().isAutoRedirect()) {
                // 设定开放认证标识
                response.addCookie(new Cookie(OAuth2AccessToken.AUTH_PARAM_VALUE, "1"));
                // 登出
                authenticationEntryPoint.logout(request);
                // token不存在或者无效
                response.sendRedirect(authenticationEntryPoint.redirectUrl(parsed));
                return AuthStatus.REDIRECT;
            }
        }
        return AuthStatus.FAIL;
    }

    /**
     * 认证成功的回调
     *
     * @param request     请求
     * @param accessToken token
     */
    private boolean authenticateSuccess(HttpServletRequest request, String accessToken) {
        HttpSession session = request.getSession();
        // 自动补全信息
        if (!client.getSessionConverter().isComplete(session)) {
            SSOUserInfo userInfo = authenticationEntryPoint.getUserInfo(accessToken);
            request.setAttribute("user", userInfo);
            Object user = UserConvertUtils.convert(client.getUserService(), userInfo);
            return client.getSessionConverter().convert(session, user);
        }
        return true;
    }

    /**
     * 刷新accessToken
     *
     * @param response     响应
     * @param refreshToken 刷新Token
     * @return 结果
     */
    private boolean refreshAccessToken(HttpServletResponse response, String refreshToken) {
        // token无效或者木有,但是refreshToken存在,尝试刷新
        if (null != refreshToken) {
            OAuthSSOToken refreshedToken = authenticationEntryPoint.refreshAccessToken(refreshToken);
            if (null == refreshedToken) {
                return false;
            }
            // 写入Cookie
            for (Cookie cookie : refreshedToken.toCookies()) {
                response.addCookie(cookie);
            }
            return true;
        }
        return false;
    }

    /**
     * 判断当前请求是否是资源请求,如果是,则放行
     *
     * @return 结果
     */
    private boolean checkResource(String requestURI) {
        for (String type : RESOURCE_TYPES) {
            if (requestURI.endsWith(type)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 检查放行规则
     *
     * @param uri  uri
     * @param uris uris
     * @return 结果
     */
    private boolean checkAllowed(String uri, Set uris) {
        for (String perUri : uris) {
            if (perUri.endsWith("/**") && uri.startsWith(perUri.substring(0, perUri.indexOf("/**"))) || uri.equals(perUri)) {
                return true;
            }
        }
        return false;
    }

    private static class SingletonHolder {

        private static final OAuthAuthenticator INSTANCE = new OAuthAuthenticator();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy