mirror of
https://gitee.com/dromara/MaxKey.git
synced 2025-12-07 17:38:32 +08:00
oauth2 Approval fix & sso login history
This commit is contained in:
parent
e0e299ff80
commit
6cad9f0ca2
@ -25,6 +25,8 @@ import org.maxkey.authz.oauth2.provider.OAuth2Authentication;
|
||||
import org.maxkey.authz.oauth2.provider.approval.Approval.ApprovalStatus;
|
||||
import org.maxkey.authz.oauth2.provider.token.AuthorizationServerTokenServices;
|
||||
import org.maxkey.authz.oauth2.provider.token.TokenStore;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* An {@link ApprovalStore} that works with an existing {@link TokenStore}, extracting implicit {@link Approval
|
||||
@ -38,6 +40,8 @@ import org.maxkey.authz.oauth2.provider.token.TokenStore;
|
||||
*/
|
||||
public class TokenApprovalStore implements ApprovalStore {
|
||||
|
||||
static final Logger _logger = LoggerFactory.getLogger(TokenApprovalStore.class);
|
||||
|
||||
private TokenStore store;
|
||||
|
||||
/**
|
||||
@ -55,6 +59,7 @@ public class TokenApprovalStore implements ApprovalStore {
|
||||
*/
|
||||
@Override
|
||||
public boolean addApprovals(Collection<Approval> approvals) {
|
||||
_logger.debug("add Approvals...");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -65,6 +70,7 @@ public class TokenApprovalStore implements ApprovalStore {
|
||||
*/
|
||||
@Override
|
||||
public boolean revokeApprovals(Collection<Approval> approvals) {
|
||||
_logger.debug("revoke Approvals " + approvals);
|
||||
boolean success = true;
|
||||
for (Approval approval : approvals) {
|
||||
Collection<OAuth2AccessToken> tokens = store.findTokensByClientIdAndUserName(approval.getClientId(), approval.getUserId());
|
||||
@ -87,14 +93,22 @@ public class TokenApprovalStore implements ApprovalStore {
|
||||
*/
|
||||
@Override
|
||||
public Collection<Approval> getApprovals(String userId, String clientId) {
|
||||
_logger.trace("userId " + userId+" , clientId " + clientId);
|
||||
Collection<Approval> result = new HashSet<Approval>();
|
||||
Collection<OAuth2AccessToken> tokens = store.findTokensByClientIdAndUserName(clientId, userId);
|
||||
_logger.trace("tokens Collection " + tokens);
|
||||
for (OAuth2AccessToken token : tokens) {
|
||||
_logger.trace("token " + token);
|
||||
if(token != null) {
|
||||
OAuth2Authentication authentication = store.readAuthentication(token);
|
||||
_logger.trace("authentication " + authentication);
|
||||
if (authentication != null) {
|
||||
Date expiresAt = token.getExpiration();
|
||||
for (String scope : token.getScope()) {
|
||||
result.add(new Approval(userId, clientId, scope, expiresAt, ApprovalStatus.APPROVED));
|
||||
Approval approval = new Approval(userId, clientId, scope, expiresAt, ApprovalStatus.APPROVED);
|
||||
result.add(approval);
|
||||
_logger.trace("add approval " + approval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +77,8 @@ public class OAuth20AccessConfirmationEndpoint {
|
||||
*/
|
||||
@RequestMapping(OAuth2Constants.ENDPOINT.ENDPOINT_APPROVAL_CONFIRM)
|
||||
public ModelAndView getAccessConfirmation(
|
||||
@RequestParam Map<String, Object> model) throws Exception {
|
||||
@RequestParam Map<String, Object> model) {
|
||||
try {
|
||||
model.remove("authorizationRequest");
|
||||
|
||||
// Map<String, Object> model
|
||||
@ -114,11 +115,14 @@ public class OAuth20AccessConfirmationEndpoint {
|
||||
if(!model.containsKey(OAuth2Constants.PARAMETER.APPROVAL_PROMPT)) {
|
||||
model.put(OAuth2Constants.PARAMETER.APPROVAL_PROMPT, client.getApprovalPrompt());
|
||||
}
|
||||
}catch(Exception e) {
|
||||
_logger.debug("OAuth Access Confirmation process error." ,e);
|
||||
}
|
||||
|
||||
ModelAndView modelAndView = new ModelAndView("authorize/oauth_access_confirmation");
|
||||
_logger.debug("Confirmation details ");
|
||||
_logger.trace("Confirmation details ");
|
||||
for (Object key : model.keySet()) {
|
||||
_logger.debug("key " + key +"=" + model.get(key));
|
||||
_logger.trace("key " + key +"=" + model.get(key));
|
||||
}
|
||||
modelAndView.addObject("model", model);
|
||||
return modelAndView;
|
||||
|
||||
@ -32,6 +32,8 @@ import org.maxkey.authz.oauth2.provider.token.TokenStore;
|
||||
import org.maxkey.persistence.redis.RedisConnection;
|
||||
import org.maxkey.persistence.redis.RedisConnectionFactory;
|
||||
import org.maxkey.util.ObjectTransformer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ -39,16 +41,17 @@ import java.util.Date;
|
||||
* @author efenderbosch
|
||||
*/
|
||||
public class RedisTokenStore implements TokenStore {
|
||||
static final Logger _logger = LoggerFactory.getLogger(RedisTokenStore.class);
|
||||
|
||||
private static final String ACCESS = "REDIS_OAUTH_V20_access:";
|
||||
private static final String AUTH_TO_ACCESS = "REDIS_OAUTH_V20_auth_to_access:";
|
||||
private static final String AUTH = "REDIS_OAUTH_V20_auth:";
|
||||
private static final String REFRESH_AUTH = "REDIS_OAUTH_V20_refresh_auth:";
|
||||
private static final String ACCESS_TO_REFRESH = "REDIS_OAUTH_V20_access_to_refresh:";
|
||||
private static final String REFRESH = "REDIS_OAUTH_V20_refresh:";
|
||||
private static final String REFRESH_TO_ACCESS = "REDIS_OAUTH_V20_refresh_to_access:";
|
||||
private static final String CLIENT_ID_TO_ACCESS = "REDIS_OAUTH_V20_client_id_to_access:";
|
||||
private static final String UNAME_TO_ACCESS = "REDIS_OAUTH_V20_uname_to_access:";
|
||||
private static final String ACCESS = "REDIS_OAUTH_V20_ACCESS_";
|
||||
private static final String AUTH_TO_ACCESS = "REDIS_OAUTH_V20_AUTH_TO_ACCESS_";
|
||||
private static final String AUTH = "REDIS_OAUTH_V20_AUTH_";
|
||||
private static final String REFRESH_AUTH = "REDIS_OAUTH_V20_REFRESH_AUTH_";
|
||||
private static final String ACCESS_TO_REFRESH = "REDIS_OAUTH_V20_ACCESS_TO_REFRESH_";
|
||||
private static final String REFRESH = "REDIS_OAUTH_V20_REFRESH_";
|
||||
private static final String REFRESH_TO_ACCESS = "REDIS_OAUTH_V20_REFRESH_TO_ACCESS_";
|
||||
private static final String CLIENT_ID_TO_ACCESS = "REDIS_OAUTH_V20_CLIENT_ID_TO_ACCESS_";
|
||||
private static final String UNAME_TO_ACCESS = "REDIS_OAUTH_V20_UNAME_TO_ACCESS_";
|
||||
|
||||
private final RedisConnectionFactory connectionFactory;
|
||||
private AuthenticationKeyGenerator authenticationKeyGenerator = new DefaultAuthenticationKeyGenerator();
|
||||
@ -77,6 +80,7 @@ public class RedisTokenStore implements TokenStore {
|
||||
String key = authenticationKeyGenerator.extractKey(authentication);
|
||||
String serializedKey = (AUTH_TO_ACCESS + key);
|
||||
RedisConnection conn = getConnection();
|
||||
try {
|
||||
OAuth2AccessToken accessToken =conn.getObject(serializedKey);
|
||||
if (accessToken != null
|
||||
&& !key.equals(authenticationKeyGenerator.extractKey(readAuthentication(accessToken.getValue())))) {
|
||||
@ -86,6 +90,9 @@ public class RedisTokenStore implements TokenStore {
|
||||
storeAccessToken(accessToken, authentication);
|
||||
}
|
||||
return accessToken;
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -95,9 +102,14 @@ public class RedisTokenStore implements TokenStore {
|
||||
|
||||
@Override
|
||||
public OAuth2Authentication readAuthentication(String token) {
|
||||
_logger.trace("read Authentication by token " + token + " , token key " + AUTH + token);
|
||||
RedisConnection conn = getConnection();
|
||||
try {
|
||||
OAuth2Authentication auth = conn.getObject(AUTH + token);
|
||||
return auth;
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -122,6 +134,11 @@ public class RedisTokenStore implements TokenStore {
|
||||
String authToAccessKey = (AUTH_TO_ACCESS + authenticationKeyGenerator.extractKey(authentication));
|
||||
String approvalKey = (UNAME_TO_ACCESS + getApprovalKey(authentication));
|
||||
String clientId = (CLIENT_ID_TO_ACCESS + authentication.getOAuth2Request().getClientId());
|
||||
_logger.trace("accessKey " + accessKey);
|
||||
_logger.trace("authKey " + authKey);
|
||||
_logger.trace("authToAccessKey " + authToAccessKey);
|
||||
_logger.trace("approvalKey " + approvalKey);
|
||||
_logger.trace("clientId " + clientId);
|
||||
|
||||
RedisConnection conn = getConnection();
|
||||
try {
|
||||
@ -146,8 +163,10 @@ public class RedisTokenStore implements TokenStore {
|
||||
String refresh = (token.getRefreshToken().getValue());
|
||||
String auth = (token.getValue());
|
||||
String refreshToAccessKey = (REFRESH_TO_ACCESS + token.getRefreshToken().getValue());
|
||||
_logger.trace("refreshToAccessKey " + refreshToAccessKey);
|
||||
conn.set(refreshToAccessKey, auth);
|
||||
String accessToRefreshKey = (ACCESS_TO_REFRESH + token.getValue());
|
||||
_logger.trace("accessToRefreshKey " + accessToRefreshKey);
|
||||
conn.set(accessToRefreshKey, refresh);
|
||||
if (refreshToken instanceof ExpiringOAuth2RefreshToken) {
|
||||
ExpiringOAuth2RefreshToken expiringRefreshToken = (ExpiringOAuth2RefreshToken) refreshToken;
|
||||
@ -173,7 +192,7 @@ public class RedisTokenStore implements TokenStore {
|
||||
}
|
||||
|
||||
private static String getApprovalKey(String clientId, String userName) {
|
||||
return clientId + (userName == null ? "" : ":" + userName);
|
||||
return clientId + (userName == null ? "" : "_" + userName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -184,9 +203,13 @@ public class RedisTokenStore implements TokenStore {
|
||||
@Override
|
||||
public OAuth2AccessToken readAccessToken(String tokenValue) {
|
||||
RedisConnection conn = getConnection();
|
||||
try {
|
||||
String key = (ACCESS + tokenValue);
|
||||
OAuth2AccessToken accessToken = conn.getObject(key);
|
||||
return accessToken;
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAccessToken(String tokenValue) {
|
||||
@ -251,9 +274,13 @@ public class RedisTokenStore implements TokenStore {
|
||||
public OAuth2RefreshToken readRefreshToken(String tokenValue) {
|
||||
String key = (REFRESH + tokenValue);
|
||||
RedisConnection conn = getConnection();
|
||||
try {
|
||||
OAuth2RefreshToken refreshToken = conn.getObject(key);
|
||||
conn.close();
|
||||
return refreshToken;
|
||||
} finally {
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -309,6 +336,7 @@ public class RedisTokenStore implements TokenStore {
|
||||
@Override
|
||||
public Collection<OAuth2AccessToken> findTokensByClientIdAndUserName(String clientId, String userName) {
|
||||
String approvalKey = (UNAME_TO_ACCESS + getApprovalKey(clientId, userName));
|
||||
_logger.trace("approvalKey " + approvalKey);
|
||||
List<String> stringList = null;
|
||||
RedisConnection conn = getConnection();
|
||||
try {
|
||||
@ -321,6 +349,7 @@ public class RedisTokenStore implements TokenStore {
|
||||
}
|
||||
List<OAuth2AccessToken> accessTokens = new ArrayList<OAuth2AccessToken>(stringList.size());
|
||||
for (String str : stringList) {
|
||||
//accessToken may expired
|
||||
OAuth2AccessToken accessToken = conn.getObject(str);
|
||||
accessTokens.add(accessToken);
|
||||
}
|
||||
@ -330,6 +359,7 @@ public class RedisTokenStore implements TokenStore {
|
||||
@Override
|
||||
public Collection<OAuth2AccessToken> findTokensByClientId(String clientId) {
|
||||
String key = (CLIENT_ID_TO_ACCESS + clientId);
|
||||
_logger.trace("TokensByClientId " + key);
|
||||
List<String> stringList = null;
|
||||
RedisConnection conn = getConnection();
|
||||
try {
|
||||
|
||||
@ -211,12 +211,13 @@ public class MaxKeyMvcConfig implements WebMvcConfigurer {
|
||||
registry.addInterceptor(historyLoginAppAdapter)
|
||||
.addPathPatterns("/authz/basic/*")
|
||||
.addPathPatterns("/authz/ltpa/*")
|
||||
.addPathPatterns("/authz/desktop/*")
|
||||
.addPathPatterns("/authz/api/*")
|
||||
.addPathPatterns("/authz/formbased/*")
|
||||
.addPathPatterns("/authz/tokenbased/*")
|
||||
.addPathPatterns("/authz/saml20/idpinit/*")
|
||||
.addPathPatterns("/authz/saml20/assertion")
|
||||
.addPathPatterns("/authz/cas/granting")
|
||||
.addPathPatterns("/authz/oauth/v20/approval_confirm")
|
||||
;
|
||||
_logger.debug("add HistoryLoginAppAdapter");
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user