mirror of
https://gitee.com/dromara/MaxKey.git
synced 2025-12-08 01:48:33 +08:00
OAuth2Exception
This commit is contained in:
parent
3497aa5d26
commit
924cff9872
@ -26,6 +26,8 @@ import java.util.Set;
|
|||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
import org.maxkey.authz.oauth2.common.exceptions.OAuth2Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic access token for OAuth 2.
|
* Basic access token for OAuth 2.
|
||||||
*
|
*
|
||||||
@ -48,7 +50,9 @@ public class DefaultOAuth2AccessToken implements Serializable, OAuth2AccessToken
|
|||||||
private Set<String> scope;
|
private Set<String> scope;
|
||||||
|
|
||||||
private Map<String, Object> additionalInformation = Collections.emptyMap();
|
private Map<String, Object> additionalInformation = Collections.emptyMap();
|
||||||
|
|
||||||
|
private OAuth2Exception oauth2Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an access token from the value provided.
|
* Create an access token from the value provided.
|
||||||
*/
|
*/
|
||||||
@ -78,6 +82,10 @@ public class DefaultOAuth2AccessToken implements Serializable, OAuth2AccessToken
|
|||||||
setTokenType(accessToken.getTokenType());
|
setTokenType(accessToken.getTokenType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DefaultOAuth2AccessToken(OAuth2Exception oauth2Exception) {
|
||||||
|
this.oauth2Exception = oauth2Exception;
|
||||||
|
}
|
||||||
|
|
||||||
public void setValue(String value) {
|
public void setValue(String value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
@ -258,4 +266,10 @@ public class DefaultOAuth2AccessToken implements Serializable, OAuth2AccessToken
|
|||||||
this.additionalInformation = new LinkedHashMap<String, Object>(additionalInformation);
|
this.additionalInformation = new LinkedHashMap<String, Object>(additionalInformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OAuth2Exception getOAuth2Exception() {
|
||||||
|
|
||||||
|
return this.oauth2Exception;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,8 @@ import java.util.Date;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.maxkey.authz.oauth2.common.exceptions.OAuth2Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
*
|
*
|
||||||
@ -59,6 +61,11 @@ public interface OAuth2AccessToken extends Serializable {
|
|||||||
* href="http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.3">Section 3.3</a>
|
* href="http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.3">Section 3.3</a>
|
||||||
*/
|
*/
|
||||||
public static String SCOPE = "scope";
|
public static String SCOPE = "scope";
|
||||||
|
|
||||||
|
public static String ERROR = "error";
|
||||||
|
|
||||||
|
public static String ERROR_DESCRIPTION = "error_description";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The additionalInformation map is used by the token serializers to export any fields used by extensions of OAuth.
|
* The additionalInformation map is used by the token serializers to export any fields used by extensions of OAuth.
|
||||||
@ -73,6 +80,8 @@ public interface OAuth2AccessToken extends Serializable {
|
|||||||
OAuth2RefreshToken getRefreshToken();
|
OAuth2RefreshToken getRefreshToken();
|
||||||
|
|
||||||
String getTokenType();
|
String getTokenType();
|
||||||
|
|
||||||
|
OAuth2Exception getOAuth2Exception();
|
||||||
|
|
||||||
boolean isExpired();
|
boolean isExpired();
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,11 @@ import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
|||||||
*/
|
*/
|
||||||
public final class OAuth2AccessTokenJackson2Serializer extends StdSerializer<OAuth2AccessToken> {
|
public final class OAuth2AccessTokenJackson2Serializer extends StdSerializer<OAuth2AccessToken> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -7323248504425950254L;
|
||||||
|
|
||||||
public OAuth2AccessTokenJackson2Serializer() {
|
public OAuth2AccessTokenJackson2Serializer() {
|
||||||
super(OAuth2AccessToken.class);
|
super(OAuth2AccessToken.class);
|
||||||
}
|
}
|
||||||
@ -42,26 +47,31 @@ public final class OAuth2AccessTokenJackson2Serializer extends StdSerializer<OAu
|
|||||||
public void serialize(OAuth2AccessToken token, JsonGenerator jgen, SerializerProvider provider) throws IOException,
|
public void serialize(OAuth2AccessToken token, JsonGenerator jgen, SerializerProvider provider) throws IOException,
|
||||||
JsonGenerationException {
|
JsonGenerationException {
|
||||||
jgen.writeStartObject();
|
jgen.writeStartObject();
|
||||||
jgen.writeStringField(OAuth2AccessToken.ACCESS_TOKEN, token.getValue());
|
if(token.getOAuth2Exception()==null) {
|
||||||
jgen.writeStringField(OAuth2AccessToken.TOKEN_TYPE, token.getTokenType());
|
jgen.writeStringField(OAuth2AccessToken.ACCESS_TOKEN, token.getValue());
|
||||||
OAuth2RefreshToken refreshToken = token.getRefreshToken();
|
jgen.writeStringField(OAuth2AccessToken.TOKEN_TYPE, token.getTokenType());
|
||||||
if (refreshToken != null) {
|
OAuth2RefreshToken refreshToken = token.getRefreshToken();
|
||||||
jgen.writeStringField(OAuth2AccessToken.REFRESH_TOKEN, refreshToken.getValue());
|
if (refreshToken != null) {
|
||||||
}
|
jgen.writeStringField(OAuth2AccessToken.REFRESH_TOKEN, refreshToken.getValue());
|
||||||
Date expiration = token.getExpiration();
|
|
||||||
if (expiration != null) {
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
jgen.writeNumberField(OAuth2AccessToken.EXPIRES_IN, (expiration.getTime() - now) / 1000);
|
|
||||||
}
|
|
||||||
Set<String> scope = token.getScope();
|
|
||||||
if (scope != null && !scope.isEmpty()) {
|
|
||||||
StringBuffer scopes = new StringBuffer();
|
|
||||||
for (String s : scope) {
|
|
||||||
Assert.hasLength(s, "Scopes cannot be null or empty. Got " + scope + "");
|
|
||||||
scopes.append(s);
|
|
||||||
scopes.append(" ");
|
|
||||||
}
|
}
|
||||||
jgen.writeStringField(OAuth2AccessToken.SCOPE, scopes.substring(0, scopes.length() - 1));
|
Date expiration = token.getExpiration();
|
||||||
|
if (expiration != null) {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
jgen.writeNumberField(OAuth2AccessToken.EXPIRES_IN, (expiration.getTime() - now) / 1000);
|
||||||
|
}
|
||||||
|
Set<String> scope = token.getScope();
|
||||||
|
if (scope != null && !scope.isEmpty()) {
|
||||||
|
StringBuffer scopes = new StringBuffer();
|
||||||
|
for (String s : scope) {
|
||||||
|
Assert.hasLength(s, "Scopes cannot be null or empty. Got " + scope + "");
|
||||||
|
scopes.append(s);
|
||||||
|
scopes.append(" ");
|
||||||
|
}
|
||||||
|
jgen.writeStringField(OAuth2AccessToken.SCOPE, scopes.substring(0, scopes.length() - 1));
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
jgen.writeStringField(OAuth2AccessToken.ERROR, token.getOAuth2Exception().getOAuth2ErrorCode());
|
||||||
|
jgen.writeStringField(OAuth2AccessToken.ERROR_DESCRIPTION, token.getOAuth2Exception().getMessage());
|
||||||
}
|
}
|
||||||
Map<String, Object> additionalInformation = token.getAdditionalInformation();
|
Map<String, Object> additionalInformation = token.getAdditionalInformation();
|
||||||
for (String key : additionalInformation.keySet()) {
|
for (String key : additionalInformation.keySet()) {
|
||||||
|
|||||||
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.maxkey.authz.oauth2.provider.endpoint;
|
package org.maxkey.authz.oauth2.provider.endpoint;
|
||||||
|
|
||||||
import java.security.Principal;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -24,10 +23,12 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.maxkey.authn.SigninPrincipal;
|
import org.maxkey.authn.SigninPrincipal;
|
||||||
|
import org.maxkey.authz.oauth2.common.DefaultOAuth2AccessToken;
|
||||||
import org.maxkey.authz.oauth2.common.OAuth2AccessToken;
|
import org.maxkey.authz.oauth2.common.OAuth2AccessToken;
|
||||||
import org.maxkey.authz.oauth2.common.exceptions.InvalidClientException;
|
import org.maxkey.authz.oauth2.common.exceptions.InvalidClientException;
|
||||||
import org.maxkey.authz.oauth2.common.exceptions.InvalidGrantException;
|
import org.maxkey.authz.oauth2.common.exceptions.InvalidGrantException;
|
||||||
import org.maxkey.authz.oauth2.common.exceptions.InvalidRequestException;
|
import org.maxkey.authz.oauth2.common.exceptions.InvalidRequestException;
|
||||||
|
import org.maxkey.authz.oauth2.common.exceptions.OAuth2Exception;
|
||||||
import org.maxkey.authz.oauth2.common.exceptions.UnsupportedGrantTypeException;
|
import org.maxkey.authz.oauth2.common.exceptions.UnsupportedGrantTypeException;
|
||||||
import org.maxkey.authz.oauth2.common.util.OAuth2Utils;
|
import org.maxkey.authz.oauth2.common.util.OAuth2Utils;
|
||||||
import org.maxkey.authz.oauth2.provider.OAuth2Authentication;
|
import org.maxkey.authz.oauth2.provider.OAuth2Authentication;
|
||||||
@ -97,64 +98,69 @@ public class TokenEndpoint extends AbstractEndpoint {
|
|||||||
public ResponseEntity<OAuth2AccessToken> postAccessToken(@RequestParam
|
public ResponseEntity<OAuth2AccessToken> postAccessToken(@RequestParam
|
||||||
Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
|
Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
|
||||||
// TokenEndpointAuthenticationFilter
|
// TokenEndpointAuthenticationFilter
|
||||||
|
OAuth2AccessToken token = null;
|
||||||
Object principal = WebContext.getAuthentication();
|
try {
|
||||||
|
Object principal = WebContext.getAuthentication();
|
||||||
if (!(principal instanceof Authentication)) {
|
|
||||||
throw new InsufficientAuthenticationException(
|
if (!(principal instanceof Authentication)) {
|
||||||
"There is no client authentication. Try adding an appropriate authentication filter.");
|
throw new InsufficientAuthenticationException(
|
||||||
}
|
"There is no client authentication. Try adding an appropriate authentication.");
|
||||||
|
|
||||||
String clientId = getClientId((Authentication)principal);
|
|
||||||
ClientDetails authenticatedClient = getClientDetailsService().loadClientByClientId(clientId);
|
|
||||||
|
|
||||||
TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(parameters, authenticatedClient);
|
|
||||||
|
|
||||||
if (clientId != null && !clientId.equals("")) {
|
|
||||||
// Only validate the client details if a client authenticated during this
|
|
||||||
// request.
|
|
||||||
if (!clientId.equals(tokenRequest.getClientId())) {
|
|
||||||
// double check to make sure that the client ID in the token request is the same as that in the
|
|
||||||
// authenticated client
|
|
||||||
throw new InvalidClientException("Given client ID does not match authenticated client");
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (authenticatedClient != null) {
|
String clientId = getClientId((Authentication)principal);
|
||||||
oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient);
|
ClientDetails authenticatedClient = getClientDetailsService().loadClientByClientId(clientId);
|
||||||
}
|
|
||||||
if (!StringUtils.hasText(tokenRequest.getGrantType())) {
|
TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(parameters, authenticatedClient);
|
||||||
throw new InvalidRequestException("Missing grant type");
|
|
||||||
}
|
if (clientId != null && !clientId.equals("")) {
|
||||||
if (tokenRequest.getGrantType().equals("implicit")) {
|
// Only validate the client details if a client authenticated during this
|
||||||
throw new InvalidGrantException("Implicit grant type not supported from token endpoint");
|
// request.
|
||||||
}
|
if (!clientId.equals(tokenRequest.getClientId())) {
|
||||||
|
// double check to make sure that the client ID in the token request is the same as that in the
|
||||||
if (isAuthCodeRequest(parameters)) {
|
// authenticated client
|
||||||
|
throw new InvalidClientException("Given client ID does not match authenticated client");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (authenticatedClient != null) {
|
||||||
|
oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient);
|
||||||
|
}
|
||||||
|
if (!StringUtils.hasText(tokenRequest.getGrantType())) {
|
||||||
|
throw new InvalidRequestException("Missing grant type");
|
||||||
|
}
|
||||||
|
if (tokenRequest.getGrantType().equals("implicit")) {
|
||||||
|
throw new InvalidGrantException("Implicit grant type not supported from token endpoint");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAuthCodeRequest(parameters)) {
|
||||||
|
// The scope was requested or determined during the authorization step
|
||||||
|
if (!tokenRequest.getScope().isEmpty()) {
|
||||||
|
logger.debug("Clearing scope of incoming token request");
|
||||||
|
tokenRequest.setScope(Collections.<String> emptySet());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The scope was requested or determined during the authorization step
|
// The scope was requested or determined during the authorization step
|
||||||
if (!tokenRequest.getScope().isEmpty()) {
|
/**crystal.sea
|
||||||
logger.debug("Clearing scope of incoming token request");
|
* code must uuid format
|
||||||
tokenRequest.setScope(Collections.<String> emptySet());
|
*/
|
||||||
|
if (parameters.get("code") != null &&!StringGenerator.uuidMatches(parameters.get("code"))) {
|
||||||
|
throw new InvalidRequestException("The code is not valid format .");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (isRefreshTokenRequest(parameters)) {
|
||||||
// The scope was requested or determined during the authorization step
|
// A refresh token has its own default scopes, so we should ignore any added by the factory here.
|
||||||
/**crystal.sea
|
tokenRequest.setScope(OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)));
|
||||||
* code must uuid format
|
}
|
||||||
*/
|
|
||||||
if (parameters.get("code") != null &&!StringGenerator.uuidMatches(parameters.get("code"))) {
|
token = getTokenGranter().grant(tokenRequest.getGrantType(), tokenRequest);
|
||||||
throw new InvalidRequestException("The code is not valid format .");
|
if (token == null) {
|
||||||
}
|
throw new UnsupportedGrantTypeException("Unsupported grant type: " + tokenRequest.getGrantType());
|
||||||
|
}
|
||||||
if (isRefreshTokenRequest(parameters)) {
|
}catch(OAuth2Exception oauth2Exception) {
|
||||||
// A refresh token has its own default scopes, so we should ignore any added by the factory here.
|
token = new DefaultOAuth2AccessToken(oauth2Exception);
|
||||||
tokenRequest.setScope(OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)));
|
}catch(InsufficientAuthenticationException authenticationException) {
|
||||||
}
|
token = new DefaultOAuth2AccessToken(new OAuth2Exception(authenticationException.getMessage()));
|
||||||
|
}
|
||||||
OAuth2AccessToken token = getTokenGranter().grant(tokenRequest.getGrantType(), tokenRequest);
|
|
||||||
if (token == null) {
|
|
||||||
throw new UnsupportedGrantTypeException("Unsupported grant type: " + tokenRequest.getGrantType());
|
|
||||||
}
|
|
||||||
|
|
||||||
return getResponse(token);
|
return getResponse(token);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user