|
|
@@ -0,0 +1,89 @@ |
|
|
|
package com.tuoheng.oauth2.authentication; |
|
|
|
|
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.HashSet; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest; |
|
|
|
|
|
|
|
import org.springframework.lang.Nullable; |
|
|
|
import org.springframework.security.core.Authentication; |
|
|
|
import org.springframework.security.core.context.SecurityContextHolder; |
|
|
|
import org.springframework.security.oauth2.core.AuthorizationGrantType; |
|
|
|
import org.springframework.security.oauth2.core.OAuth2ErrorCodes; |
|
|
|
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; |
|
|
|
import org.springframework.security.web.authentication.AuthenticationConverter; |
|
|
|
import org.springframework.util.MultiValueMap; |
|
|
|
import org.springframework.util.StringUtils; |
|
|
|
|
|
|
|
public class OAuth2ResourceOwnerPasswordAuthenticationConverter implements AuthenticationConverter { |
|
|
|
|
|
|
|
@Nullable |
|
|
|
@Override |
|
|
|
public Authentication convert(HttpServletRequest request) { |
|
|
|
|
|
|
|
// grant_type (REQUIRED) |
|
|
|
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE); |
|
|
|
if (!AuthorizationGrantType.PASSWORD.getValue().equals(grantType)) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
MultiValueMap<String, String> parameters = OAuth2EndpointUtils.getParameters(request); |
|
|
|
|
|
|
|
// scope (OPTIONAL) |
|
|
|
String scope = parameters.getFirst(OAuth2ParameterNames.SCOPE); |
|
|
|
if (StringUtils.hasText(scope) && |
|
|
|
parameters.get(OAuth2ParameterNames.SCOPE).size() != 1) { |
|
|
|
OAuth2EndpointUtils.throwError( |
|
|
|
OAuth2ErrorCodes.INVALID_REQUEST, |
|
|
|
OAuth2ParameterNames.SCOPE, |
|
|
|
OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); |
|
|
|
} |
|
|
|
|
|
|
|
Set<String> requestedScopes = null; |
|
|
|
if (StringUtils.hasText(scope)) { |
|
|
|
requestedScopes = new HashSet<>( |
|
|
|
Arrays.asList(StringUtils.delimitedListToStringArray(scope, " "))); |
|
|
|
} |
|
|
|
|
|
|
|
// username (REQUIRED) |
|
|
|
String username = parameters.getFirst(OAuth2ParameterNames.USERNAME); |
|
|
|
if (!StringUtils.hasText(username) || parameters.get(OAuth2ParameterNames.USERNAME).size() != 1) { |
|
|
|
OAuth2EndpointUtils.throwError( |
|
|
|
OAuth2ErrorCodes.INVALID_REQUEST, |
|
|
|
OAuth2ParameterNames.USERNAME, |
|
|
|
OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); |
|
|
|
} |
|
|
|
|
|
|
|
// password (REQUIRED) |
|
|
|
String password = parameters.getFirst(OAuth2ParameterNames.PASSWORD); |
|
|
|
if (!StringUtils.hasText(password) || parameters.get(OAuth2ParameterNames.PASSWORD).size() != 1) { |
|
|
|
OAuth2EndpointUtils.throwError( |
|
|
|
OAuth2ErrorCodes.INVALID_REQUEST, |
|
|
|
OAuth2ParameterNames.PASSWORD, |
|
|
|
OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); |
|
|
|
} |
|
|
|
|
|
|
|
Authentication clientPrincipal = SecurityContextHolder.getContext().getAuthentication(); |
|
|
|
if (clientPrincipal == null) { |
|
|
|
OAuth2EndpointUtils.throwError( |
|
|
|
OAuth2ErrorCodes.INVALID_REQUEST, |
|
|
|
OAuth2ErrorCodes.INVALID_CLIENT, |
|
|
|
OAuth2EndpointUtils.ACCESS_TOKEN_REQUEST_ERROR_URI); |
|
|
|
} |
|
|
|
|
|
|
|
Map<String, Object> additionalParameters = parameters |
|
|
|
.entrySet() |
|
|
|
.stream() |
|
|
|
.filter(e -> !e.getKey().equals(OAuth2ParameterNames.GRANT_TYPE) && |
|
|
|
!e.getKey().equals(OAuth2ParameterNames.SCOPE)) |
|
|
|
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().get(0))); |
|
|
|
|
|
|
|
return new OAuth2ResourceOwnerPasswordAuthenticationToken( |
|
|
|
AuthorizationGrantType.PASSWORD, clientPrincipal, requestedScopes, additionalParameters); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |