🐛 修复 client_credentials 模式登录的一些问题

This commit is contained in:
b2baccline
2021-09-01 11:55:21 +08:00
parent 761de62e5a
commit f3913fe7c8
5 changed files with 92 additions and 6 deletions

View File

@@ -3,6 +3,7 @@ package com.hccake.ballcat.auth;
import com.hccake.ballcat.common.security.constant.TokenAttributeNameConstants;
import com.hccake.ballcat.common.security.userdetails.User;
import com.hccake.ballcat.system.model.vo.SysUserInfo;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
@@ -26,8 +27,12 @@ public class CustomTokenEnhancer implements TokenEnhancer {
*/
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
Object principal = authentication.getUserAuthentication().getPrincipal();
Authentication userAuthentication = authentication.getUserAuthentication();
if (userAuthentication == null) {
return accessToken;
}
Object principal = userAuthentication.getPrincipal();
if (principal instanceof User) {
User user = (User) principal;
// token 附属信息

View File

@@ -29,9 +29,7 @@ public class LoginCaptchaFilter extends OncePerRequestFilter {
private static final String CAPTCHA_VERIFICATION_PARAM = "captchaVerification";
private static final String GRANT_TYPE_AUTHORIZATION_CODE = "authorization_code";
private static final String GRANT_TYPE_REFRESH_TOKEN = "refresh_token";
private static final String GRANT_TYPE_PASSWORD = "password";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
@@ -43,9 +41,9 @@ public class LoginCaptchaFilter extends OncePerRequestFilter {
return;
}
// 如果是授权码模式或者刷新token请求则直接放行
// 只对 password 的 grant_type 进行拦截处理
String grantType = request.getParameter("grant_type");
if (GRANT_TYPE_AUTHORIZATION_CODE.equals(grantType) || GRANT_TYPE_REFRESH_TOKEN.equals(grantType)) {
if (!GRANT_TYPE_PASSWORD.equals(grantType)) {
filterChain.doFilter(request, response);
return;
}

View File

@@ -1,16 +1,20 @@
package com.hccake.ballcat.common.security.oauth2.server.resource;
import com.hccake.ballcat.common.security.userdetails.ClientPrincipal;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.server.resource.introspection.BadOpaqueTokenException;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import java.util.HashMap;
/**
* 共享存储的不透明令牌的处理器
*
@@ -25,6 +29,8 @@ public class SharedStoredOpaqueTokenIntrospector implements OpaqueTokenIntrospec
private final TokenStore tokenStore;
private static final String CLIENT_CREDENTIALS = "client_credentials";
/**
* @see DefaultTokenServices#loadAuthentication(java.lang.String)
* @param accessTokenValue token
@@ -47,6 +53,14 @@ public class SharedStoredOpaqueTokenIntrospector implements OpaqueTokenIntrospec
throw new BadOpaqueTokenException("Invalid access token: " + accessTokenValue);
}
OAuth2Request oAuth2Request = result.getOAuth2Request();
if (oAuth2Request != null && CLIENT_CREDENTIALS.equals(oAuth2Request.getGrantType())) {
ClientPrincipal clientPrincipal = new ClientPrincipal(oAuth2Request.getClientId(), new HashMap<>(8),
oAuth2Request.getAuthorities());
clientPrincipal.setScope(oAuth2Request.getScope());
return clientPrincipal;
}
return (OAuth2User) result.getPrincipal();
}

View File

@@ -0,0 +1,53 @@
package com.hccake.ballcat.common.security.userdetails;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
import java.util.*;
/**
* OAuth2 Client 实体封装对象
*
* @author hccake
*/
public class ClientPrincipal implements OAuth2AuthenticatedPrincipal {
private final String clientId;
private final Map<String, Object> attributes;
private final Collection<? extends GrantedAuthority> authorities;
private Set<String> scope = new HashSet<>();
public Set<String> getScope() {
return scope;
}
public void setScope(Collection<String> scope) {
this.scope = Collections.unmodifiableSet(scope == null ? new LinkedHashSet<>() : new LinkedHashSet<>(scope));
}
@Override
public Map<String, Object> getAttributes() {
return attributes;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getName() {
return clientId;
}
public ClientPrincipal(String clientId, Map<String, Object> attributes,
Collection<? extends GrantedAuthority> authorities) {
this.clientId = clientId;
this.attributes = attributes;
this.authorities = authorities;
}
}

View File

@@ -1,6 +1,7 @@
package com.hccake.ballcat.common.security.util;
import com.hccake.ballcat.common.security.constant.SecurityConstants;
import com.hccake.ballcat.common.security.userdetails.ClientPrincipal;
import com.hccake.ballcat.common.security.userdetails.User;
import lombok.experimental.UtilityClass;
import org.springframework.security.core.Authentication;
@@ -61,4 +62,19 @@ public class SecurityUtils {
return userDetails != null && SecurityConstants.TEST_CLIENT_ID.equals(userDetails.getUsername());
}
/**
* 获取客户端信息
*/
public ClientPrincipal getClientPrincipal() {
Authentication authentication = getAuthentication();
if (authentication == null) {
return null;
}
Object principal = authentication.getPrincipal();
if (principal instanceof ClientPrincipal) {
return (ClientPrincipal) principal;
}
return null;
}
}