com.flyfish.oauth.entry.ScribeAuthenticationEntryPoint Maven / Gradle / Ivy
package com.flyfish.oauth.entry;
import com.flyfish.oauth.builder.OAuthStateBuilder;
import com.flyfish.oauth.builder.RandomOAuthStateBuilder;
import com.flyfish.oauth.configuration.OAuth2SsoProperties;
import com.flyfish.oauth.domain.OAuthSSOToken;
import com.flyfish.oauth.entry.scribe.DynamicOAuth20Service;
import com.flyfish.oauth.entry.scribe.SecurityServerApi;
import com.flyfish.oauth.utils.OAuthRequestParser;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.model.OAuth2AccessTokenErrorResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
/**
* 基于ScribeJava社区开源组件提供的认证点
*
* @author wangyu
*/
@Slf4j
public class ScribeAuthenticationEntryPoint extends AbstractAuthenticationEntryPoint {
private final OAuthStateBuilder stateBuilder = new RandomOAuthStateBuilder();
private OAuth2SsoProperties properties;
private DynamicOAuth20Service oAuth20Service;
@Override
public void configure(OAuth2SsoProperties properties) {
this.properties = properties;
this.oAuth20Service = (DynamicOAuth20Service) new ServiceBuilder(properties.getClientId())
.apiSecret(properties.getClientSecret())
.defaultScope(properties.getScope())
.build(new SecurityServerApi(properties));
}
@Override
public OAuth2SsoProperties getProperties() {
return properties;
}
/**
* 获取AccessToken
*
* @return 结果
*/
@Override
public OAuthSSOToken getClientToken() {
try {
return convertToken(oAuth20Service.getAccessTokenClientCredentialsGrant());
} catch (IOException | InterruptedException | ExecutionException e) {
log.error("【OAuth鉴权】获取clientToken失败,原因:" + e.getMessage(), e);
}
return null;
}
@Override
public OAuthSSOToken getAccessToken(String code, String grantType) {
try {
return convertToken(oAuth20Service.getAccessToken(code));
} catch (IOException | InterruptedException | ExecutionException e) {
log.error("【OAuth鉴权】获取accessToken失败,原因:" + e.getMessage(), e);
}
return null;
}
@Override
public boolean checkAccessToken(String accessToken) {
try {
return oAuth20Service.checkAccessToken(accessToken).isActive();
} catch (InterruptedException | ExecutionException | IOException e) {
log.error("【OAuth鉴权】检查accessToken有效性失败,原因:" + e.getMessage(), e);
}
return false;
}
@Override
public OAuthSSOToken getAccessToken(String code, String grantType, String redirect) {
try {
return convertToken(oAuth20Service.withCallback(redirect).getAccessToken(code));
} catch (IOException | InterruptedException | ExecutionException e) {
log.error("【OAuth鉴权】获取accessToken失败,原因:" + e.getMessage(), e);
} catch (OAuth2AccessTokenErrorResponse ex) {
// 获取token失败,说明code已经失效,重新跳转校验
return new OAuthSSOToken();
}
return null;
}
/**
* 刷新当前已经失效的token,使用refreshToken
*
* @param refreshToken 刷新token
* @return 结果
*/
@Override
public OAuthSSOToken refreshAccessToken(String refreshToken) {
try {
return convertToken(oAuth20Service.refreshAccessToken(refreshToken));
} catch (IOException | InterruptedException | ExecutionException e) {
log.error("【OAuth鉴权】刷新accessToken失败,原因:" + e.getMessage(), e);
} catch (OAuth2AccessTokenErrorResponse ex) {
return null;
}
return null;
}
@Override
public String redirectUrl(OAuthRequestParser context) {
String originRedirect = context.getLocation(properties.getLocalUrl());
return oAuth20Service.withCallback(originRedirect).getAuthorizationUrl(stateBuilder.build());
}
/**
* 登出。触发登出操作
*
* @param request 请求
* @return 结果
*/
@Override
public boolean logout(HttpServletRequest request) {
// 解析请求
OAuthRequestParser parsed = OAuthRequestParser.parse(request);
try {
String accessToken = parsed.getAccessToken();
if (StringUtils.isNotBlank(accessToken)) {
oAuth20Service.revokeToken(accessToken);
return true;
}
} catch (IOException | InterruptedException | ExecutionException e) {
log.error("【OAuth鉴权】开放认证登出失败,原因:" + e.getMessage(), e);
}
return false;
}
/**
* 转换token的值
*
* @param token 第三方token
* @return 结果
*/
private OAuthSSOToken convertToken(OAuth2AccessToken token) {
OAuthSSOToken ssoToken = new OAuthSSOToken();
ssoToken.setAccessToken(token.getAccessToken());
ssoToken.setExpiresIn(token.getExpiresIn());
ssoToken.setRefreshToken(token.getRefreshToken());
ssoToken.setScope(token.getScope());
ssoToken.setUserId(token.getParameter("user_id"));
return ssoToken;
}
}