要接入客户的统一认证,之前是用在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("/");
}