使用github.scribejava做OAuth2认证

要接入客户的统一认证,之前是用在Spring上,现在在Jfinal上用scribejava库。

1.配置类
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;

/**
 * @author 谢锐彬
 * @date 2025-06-19
 * @desc
 */
public class CerberusConfig {
    private static final Prop prop = PropKit.use("support.properties");

    public static String getClientId() {
        return prop.get("cerberus.client-id");
    }

    public static String getClientSecret() {
        return prop.get("cerberus.client-secret");
    }

    public static String getDefaultScope() {
        return prop.get("cerberus.default-scope");
    }

    public static String getCallback() {
        return prop.get("cerberus.callback");
    }

    public static String getUserExchangeUrl() {
        return prop.get("cerberus.user-exchange-url");
    }

}
2.OAuth 管理器,用于管理OAuth20Service
/**
 * @author 谢锐彬
 * @date 2025-06-20
 * @desc
 */

import com.github.scribejava.core.oauth.OAuth20Service;

/**
 * OAuth 管理器,用于全局访问 OAuth20Service 实例
 */
public class OAuthManager {
    private static OAuth20Service oAuth20Service;

    /**
     * 设置 OAuth20Service 实例
     */
    public static void setService(OAuth20Service service) {
        oAuth20Service = service;
    }

    /**
     * 获取当前配置的 OAuth20Service 实例
     */
    public static OAuth20Service getService() {
        if (oAuth20Service == null) {
            throw new IllegalStateException("OAuth20Service 未初始化");
        }
        return oAuth20Service;
    }
}
3.DefaultApi20实现类
import cn.support.common.config.CerberusConfig;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.scribejava.core.builder.api.DefaultApi20;
import com.github.scribejava.core.extractors.TokenExtractor;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.model.ParameterList;
import com.github.scribejava.core.model.Verb;

import java.util.Map;

/**
 * @author 谢锐彬
 * @date 2025-06-20
 * @desc
 */
public class OauthApi extends DefaultApi20 {
    private static final String AUTHORIZE_URL = "authorize地址";
    private static final String ACCESS_TOKEN_URL = "token地址";

    @Override
    public TokenExtractor getAccessTokenExtractor() {
        return response -> {
            JSONObject json = JSON.parseObject(response.getBody());
            return new OAuth2AccessToken(json.getString("access_token"));
        };
    }

    @Override
    public String getAuthorizationUrl(String responseType, String apiKey, String callback, String scope, String state, Map<String, String> additionalParams) {
        ParameterList parameters = new ParameterList(additionalParams);
        parameters.add("response_type", responseType);
        parameters.add("client_id", apiKey);

        if (callback != null) {
            parameters.add("redirect_uri", callback);
        }

        if (scope != null) {
            parameters.add("scope", scope);
        }else {
            parameters.add("scope", CerberusConfig.getDefaultScope());
        }

        if (state != null) {
            parameters.add("state", state);
        }

        return parameters.appendTo(this.getAuthorizationBaseUrl());
    }

    @Override
    public Verb getAccessTokenVerb() {
        return Verb.POST;
    }

    @Override
    public String getAccessTokenEndpoint() {
        return ACCESS_TOKEN_URL;
    }

    @Override
    protected String getAuthorizationBaseUrl() {
        return AUTHORIZE_URL;
    }

    private static final OauthApi INSTANCE = new OauthApi();

    public static OauthApi instance() {
        return INSTANCE;
    }
}
4.App启动的时候初始化
LOG.debug("配置OAUTH2:onStart");
// 初始化 OAuth20Service
OAuth20Service service = new ServiceBuilder(CerberusConfig.getClientId())
       .apiKey(CerberusConfig.getClientId())
       .apiSecret(CerberusConfig.getClientSecret())
       .callback(CerberusConfig.getCallback())
       .build(OauthApi.instance());

// 存入缓存或静态变量中供控制器使用
OAuthManager.setService(service);
5.登录发起和回调
/**
 * OAuth2登录发起接口
 */
public void authorize() {
    log.info("进入OAuth2登录发起接口");
    String authUrl = OAuthManager.getService().createAuthorizationUrlBuilder().build();
    redirect(authUrl);
}

public void callback() throws Exception {
    log.info("进入OAuth2登录回调接口");
    String code = getPara("code");
    // 获取 Access Token
    OAuth2AccessToken accessToken = OAuthManager.getService().getAccessToken(code);

    // 请求用户信息接口
    OAuthRequest request = new OAuthRequest(Verb.GET, CerberusConfig.getUserExchangeUrl());
    OAuthManager.getService().signRequest(accessToken, request);
    Response response = OAuthManager.getService().execute(request);

    // 解析用户信息
    String userInfoJson = response.getBody();
    log.info("用户信息: {}", userInfoJson);
    CerberusEmployee employee = JSON.toJavaObject(JSON.parseObject(userInfoJson), CerberusEmployee.class);
    Ret ret = userService.getSystemUser(employee);
    if(ret.isFail()){
        renderError(500,"系统错误,请联系管理员。");
        return;
    }
    
    .... 系统登录其它代码。
    
    // 跳转回前端页面带 token
    redirect("/");
}


评论区

zzutligang

2025-06-25 17:55

收藏,备用

热门分享

扫码入社