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