APPROVAL_PROMPT

This commit is contained in:
MaxKey
2021-04-24 09:11:26 +08:00
parent 53be09ec8a
commit 4157302d22
11 changed files with 74 additions and 56 deletions
Binary file not shown.
@@ -39,6 +39,12 @@ public class OAuth2Constants {
public static final String CODE = "code"; public static final String CODE = "code";
public static final String TOKEN = "token";
public static final String TOKEN_TYPE = "token_type";
public static final String EXPIRES_IN = "expires_in"; public static final String EXPIRES_IN = "expires_in";
/** /**
@@ -65,8 +71,16 @@ public class OAuth2Constants {
* Constant to use while parsing and formatting parameter maps for OAuth2 requests * Constant to use while parsing and formatting parameter maps for OAuth2 requests
*/ */
public static final String GRANT_TYPE = "grant_type"; public static final String GRANT_TYPE = "grant_type";
public static final String GRANT_TYPE_CODE = "code";
public static final String GRANT_TYPE_PASSWORD = "password";
public static final String GRANT_TYPE_IMPLICIT = "implicit";
public static final String GRANT_TYPE_AUTHORIZATION_CODE = "authorization_code";
public static final String GRANT_TYPE_CLIENT_CREDENTIALS = "client_credentials";
public static final String ACCESS_TOKEN = "access_token"; public static final String ACCESS_TOKEN = "access_token";
public static final String APPROVAL_PROMPT = "approval_prompt";
} }
public static class ENDPOINT{ public static class ENDPOINT{
@@ -15,13 +15,11 @@
*/ */
package org.maxkey.authz.oauth2.provider.approval.controller; package org.maxkey.authz.oauth2.provider.approval.endpoint;
import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import org.maxkey.authn.SigninPrincipal; import org.maxkey.authn.SigninPrincipal;
import org.maxkey.authz.endpoint.AuthorizeBaseEndpoint;
import org.maxkey.authz.oauth2.common.OAuth2Constants; import org.maxkey.authz.oauth2.common.OAuth2Constants;
import org.maxkey.authz.oauth2.common.util.OAuth2Utils; import org.maxkey.authz.oauth2.common.util.OAuth2Utils;
import org.maxkey.authz.oauth2.provider.AuthorizationRequest; import org.maxkey.authz.oauth2.provider.AuthorizationRequest;
@@ -34,6 +32,8 @@ import org.maxkey.authz.oauth2.provider.approval.ApprovalStore;
import org.maxkey.persistence.service.AppsService; import org.maxkey.persistence.service.AppsService;
import org.maxkey.web.WebConstants; import org.maxkey.web.WebConstants;
import org.maxkey.web.WebContext; import org.maxkey.web.WebContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@@ -50,8 +50,9 @@ import org.springframework.web.servlet.ModelAndView;
*/ */
@Controller @Controller
@SessionAttributes("authorizationRequest") @SessionAttributes("authorizationRequest")
public class OAuth20AccessConfirmationController { public class OAuth20AccessConfirmationEndpoint {
static final Logger _logger = LoggerFactory.getLogger(OAuth20AccessConfirmationEndpoint.class);
@Autowired @Autowired
@Qualifier("appsService") @Qualifier("appsService")
protected AppsService appsService; protected AppsService appsService;
@@ -78,10 +79,6 @@ public class OAuth20AccessConfirmationController {
public ModelAndView getAccessConfirmation( public ModelAndView getAccessConfirmation(
@RequestParam Map<String, Object> model) throws Exception { @RequestParam Map<String, Object> model) throws Exception {
model.remove("authorizationRequest"); model.remove("authorizationRequest");
Map<String, String> modelRequest = new HashMap<String, String>();
for (Object key : model.keySet()) {
modelRequest.put(key.toString(), model.get(key).toString());
}
// Map<String, Object> model // Map<String, Object> model
AuthorizationRequest clientAuth = AuthorizationRequest clientAuth =
@@ -111,9 +108,18 @@ public class OAuth20AccessConfirmationController {
approval.getStatus() == ApprovalStatus.APPROVED ? "true" : "false"); approval.getStatus() == ApprovalStatus.APPROVED ? "true" : "false");
} }
} }
model.put("scopes", scopes); model.put("scopes", scopes);
if(!model.containsKey(OAuth2Constants.PARAMETER.APPROVAL_PROMPT)) {
model.put(OAuth2Constants.PARAMETER.APPROVAL_PROMPT, client.getApprovalPrompt());
}
ModelAndView modelAndView = new ModelAndView("authorize/oauth_access_confirmation"); ModelAndView modelAndView = new ModelAndView("authorize/oauth_access_confirmation");
_logger.debug("Confirmation details ");
for (Object key : model.keySet()) {
_logger.debug("key " + key +"=" + model.get(key));
}
modelAndView.addObject("model", model); modelAndView.addObject("model", model);
return modelAndView; return modelAndView;
} }
@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.maxkey.authz.oauth2.provider.approval.controller; package org.maxkey.authz.oauth2.provider.approval.endpoint;
import java.util.Collection; import java.util.Collection;
@@ -20,10 +20,8 @@ import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.maxkey.authz.oauth2.common.OAuth2AccessToken; import org.maxkey.authz.oauth2.common.OAuth2AccessToken;
import org.maxkey.authz.oauth2.common.OAuth2Constants; import org.maxkey.authz.oauth2.common.OAuth2Constants;
import org.maxkey.authz.oauth2.common.exceptions.InvalidClientException; import org.maxkey.authz.oauth2.common.exceptions.InvalidClientException;
@@ -62,8 +60,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.DefaultSessionAttributeStore;
import org.springframework.web.bind.support.SessionAttributeStore;
import org.springframework.web.bind.support.SessionStatus; import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View; import org.springframework.web.servlet.View;
@@ -71,10 +67,8 @@ import org.springframework.web.servlet.view.RedirectView;
import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriTemplate; import org.springframework.web.util.UriTemplate;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.maxkey.authz.oauth2.provider.ClientDetailsService; import org.maxkey.authz.oauth2.provider.ClientDetailsService;
/** /**
@@ -114,8 +108,6 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
private UserApprovalHandler userApprovalHandler = new DefaultUserApprovalHandler(); private UserApprovalHandler userApprovalHandler = new DefaultUserApprovalHandler();
private SessionAttributeStore sessionAttributeStore = new DefaultSessionAttributeStore();
private OAuth2RequestValidator oauth2RequestValidator = new DefaultOAuth2RequestValidator(); private OAuth2RequestValidator oauth2RequestValidator = new DefaultOAuth2RequestValidator();
private String userApprovalPage = "forward:" + OAuth2Constants.ENDPOINT.ENDPOINT_APPROVAL_CONFIRM; private String userApprovalPage = "forward:" + OAuth2Constants.ENDPOINT.ENDPOINT_APPROVAL_CONFIRM;
@@ -124,9 +116,6 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
private Object implicitLock = new Object(); private Object implicitLock = new Object();
public void setSessionAttributeStore(SessionAttributeStore sessionAttributeStore) {
this.sessionAttributeStore = sessionAttributeStore;
}
public void setErrorPage(String errorPage) { public void setErrorPage(String errorPage) {
this.errorPage = errorPage; this.errorPage = errorPage;
@@ -144,7 +133,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
Set<String> responseTypes = authorizationRequest.getResponseTypes(); Set<String> responseTypes = authorizationRequest.getResponseTypes();
if (!responseTypes.contains("token") && !responseTypes.contains("code")) { if (!responseTypes.contains(OAuth2Constants.PARAMETER.TOKEN) && !responseTypes.contains(OAuth2Constants.PARAMETER.CODE)) {
throw new UnsupportedResponseTypeException("Unsupported response types: " + responseTypes); throw new UnsupportedResponseTypeException("Unsupported response types: " + responseTypes);
} }
@@ -188,10 +177,10 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
// Validation is all done, so we can check for auto approval... // Validation is all done, so we can check for auto approval...
if (authorizationRequest.isApproved()) { if (authorizationRequest.isApproved()) {
if (responseTypes.contains("token")) { if (responseTypes.contains(OAuth2Constants.PARAMETER.TOKEN)) {
return getImplicitGrantResponse(authorizationRequest); return getImplicitGrantResponse(authorizationRequest);
} }
if (responseTypes.contains("code")) { if (responseTypes.contains(OAuth2Constants.PARAMETER.CODE)) {
return new ModelAndView(getAuthorizationCodeResponse(authorizationRequest, return new ModelAndView(getAuthorizationCodeResponse(authorizationRequest,
(Authentication) principal)); (Authentication) principal));
} }
@@ -245,11 +234,11 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
if (!authorizationRequest.isApproved()) { if (!authorizationRequest.isApproved()) {
return new RedirectView(getUnsuccessfulRedirect(authorizationRequest, return new RedirectView(getUnsuccessfulRedirect(authorizationRequest,
new UserDeniedAuthorizationException("User denied access"), responseTypes.contains("token")), new UserDeniedAuthorizationException("User denied access"), responseTypes.contains(OAuth2Constants.PARAMETER.TOKEN)),
false, true, false); false, true, false);
} }
if (responseTypes.contains("token")) { if (responseTypes.contains(OAuth2Constants.PARAMETER.TOKEN)) {
return getImplicitGrantResponse(authorizationRequest).getView(); return getImplicitGrantResponse(authorizationRequest).getView();
} }
@@ -326,26 +315,26 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
url.append("#"); url.append("#");
} }
url.append("access_token={access_token}"); url.append(templateUrlVar(OAuth2Constants.PARAMETER.ACCESS_TOKEN));
url.append("&token_type={token_type}"); url.append("&").append(templateUrlVar(OAuth2Constants.PARAMETER.TOKEN_TYPE));
vars.put("access_token", accessToken.getValue()); vars.put(OAuth2Constants.PARAMETER.ACCESS_TOKEN, accessToken.getValue());
vars.put("token_type", accessToken.getTokenType()); vars.put(OAuth2Constants.PARAMETER.TOKEN_TYPE, accessToken.getTokenType());
String state = authorizationRequest.getState(); String state = authorizationRequest.getState();
if (state != null) { if (state != null) {
url.append("&state={state}"); url.append("&").append(templateUrlVar(OAuth2Constants.PARAMETER.STATE));
vars.put("state", state); vars.put(OAuth2Constants.PARAMETER.STATE, state);
} }
Date expiration = accessToken.getExpiration(); Date expiration = accessToken.getExpiration();
if (expiration != null) { if (expiration != null) {
long expires_in = (expiration.getTime() - System.currentTimeMillis()) / 1000; long expires_in = (expiration.getTime() - System.currentTimeMillis()) / 1000;
url.append("&expires_in={expires_in}"); url.append("&").append(templateUrlVar(OAuth2Constants.PARAMETER.EXPIRES_IN));
vars.put("expires_in", expires_in); vars.put(OAuth2Constants.PARAMETER.EXPIRES_IN, expires_in);
} }
String originalScope = authorizationRequest.getRequestParameters().get(OAuth2Utils.SCOPE); String originalScope = authorizationRequest.getRequestParameters().get(OAuth2Utils.SCOPE);
if (originalScope == null || !OAuth2Utils.parseParameterList(originalScope).equals(accessToken.getScope())) { if (originalScope == null || !OAuth2Utils.parseParameterList(originalScope).equals(accessToken.getScope())) {
url.append("&" + OAuth2Utils.SCOPE + "={scope}"); url.append("&").append(templateUrlVar(OAuth2Constants.PARAMETER.SCOPE));
vars.put("scope", OAuth2Utils.formatParameterList(accessToken.getScope())); vars.put(OAuth2Constants.PARAMETER.SCOPE, OAuth2Utils.formatParameterList(accessToken.getScope()));
} }
Map<String, Object> additionalInformation = accessToken.getAdditionalInformation(); Map<String, Object> additionalInformation = accessToken.getAdditionalInformation();
for (String key : additionalInformation.keySet()) { for (String key : additionalInformation.keySet()) {
@@ -359,6 +348,10 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
// Do not include the refresh token (even if there is one) // Do not include the refresh token (even if there is one)
return template.expand(vars).toString(); return template.expand(vars).toString();
} }
public String templateUrlVar(String parameterName) {
return parameterName + "={" + parameterName + "}";
}
private String generateCode(AuthorizationRequest authorizationRequest, Authentication authentication) private String generateCode(AuthorizationRequest authorizationRequest, Authentication authentication)
throws AuthenticationException { throws AuthenticationException {
@@ -376,7 +369,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
catch (OAuth2Exception e) { catch (OAuth2Exception e) {
if (authorizationRequest.getState() != null) { if (authorizationRequest.getState() != null) {
e.addAdditionalInformation("state", authorizationRequest.getState()); e.addAdditionalInformation(OAuth2Constants.PARAMETER.STATE, authorizationRequest.getState());
} }
throw e; throw e;
@@ -391,11 +384,11 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
} }
Map<String, String> query = new LinkedHashMap<String, String>(); Map<String, String> query = new LinkedHashMap<String, String>();
query.put("code", authorizationCode); query.put(OAuth2Constants.PARAMETER.CODE, authorizationCode);
String state = authorizationRequest.getState(); String state = authorizationRequest.getState();
if (state != null) { if (state != null) {
query.put("state", state); query.put(OAuth2Constants.PARAMETER.STATE, state);
} }
//this is for cas //this is for cas
@@ -421,7 +414,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
query.put("error_description", failure.getMessage()); query.put("error_description", failure.getMessage());
if (authorizationRequest.getState() != null) { if (authorizationRequest.getState() != null) {
query.put("state", authorizationRequest.getState()); query.put(OAuth2Constants.PARAMETER.STATE, authorizationRequest.getState());
} }
if (failure.getAdditionalInformation() != null) { if (failure.getAdditionalInformation() != null) {
@@ -84,7 +84,7 @@ public class CheckTokenEndpoint {
@ApiOperation(value = "OAuth 2.0 token检查接口", notes = "传递参数token",httpMethod="POST") @ApiOperation(value = "OAuth 2.0 token检查接口", notes = "传递参数token",httpMethod="POST")
@RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_CHECK_TOKEN) @RequestMapping(value = OAuth2Constants.ENDPOINT.ENDPOINT_CHECK_TOKEN)
@ResponseBody @ResponseBody
public Map<String, ?> checkToken(@RequestParam("token") String value) { public Map<String, ?> checkToken(@RequestParam(OAuth2Constants.PARAMETER.TOKEN) String value) {
OAuth2AccessToken token = resourceServerTokenServices.readAccessToken(value); OAuth2AccessToken token = resourceServerTokenServices.readAccessToken(value);
if (token == null) { if (token == null) {
@@ -133,7 +133,7 @@ public class TokenEndpoint extends AbstractEndpoint {
if (!StringUtils.hasText(tokenRequest.getGrantType())) { if (!StringUtils.hasText(tokenRequest.getGrantType())) {
throw new InvalidRequestException("Missing grant type"); throw new InvalidRequestException("Missing grant type");
} }
if (tokenRequest.getGrantType().equals("implicit")) { if (tokenRequest.getGrantType().equals(OAuth2Constants.PARAMETER.GRANT_TYPE_IMPLICIT)) {
throw new InvalidGrantException("Implicit grant type not supported from token endpoint"); throw new InvalidGrantException("Implicit grant type not supported from token endpoint");
} }
@@ -150,7 +150,8 @@ public class TokenEndpoint extends AbstractEndpoint {
/**crystal.sea /**crystal.sea
* code must uuid format * code must uuid format
*/ */
if (parameters.get("code") != null &&!StringGenerator.uuidMatches(parameters.get("code"))) { if (parameters.get(OAuth2Constants.PARAMETER.CODE) != null
&&!StringGenerator.uuidMatches(parameters.get(OAuth2Constants.PARAMETER.CODE))) {
throw new InvalidRequestException("The code is not valid format ."); throw new InvalidRequestException("The code is not valid format .");
} }
@@ -221,11 +222,11 @@ public class TokenEndpoint extends AbstractEndpoint {
} }
private boolean isRefreshTokenRequest(Map<String, String> parameters) { private boolean isRefreshTokenRequest(Map<String, String> parameters) {
return "refresh_token".equals(parameters.get("grant_type")) && parameters.get("refresh_token") != null; return "refresh_token".equals(parameters.get(OAuth2Constants.PARAMETER.GRANT_TYPE)) && parameters.get("refresh_token") != null;
} }
private boolean isAuthCodeRequest(Map<String, String> parameters) { private boolean isAuthCodeRequest(Map<String, String> parameters) {
return "authorization_code".equals(parameters.get("grant_type")) && parameters.get("code") != null; return "authorization_code".equals(parameters.get(OAuth2Constants.PARAMETER.GRANT_TYPE)) && parameters.get(OAuth2Constants.PARAMETER.CODE) != null;
} }
public void setOAuth2RequestValidator(OAuth2RequestValidator oAuth2RequestValidator) { public void setOAuth2RequestValidator(OAuth2RequestValidator oAuth2RequestValidator) {
@@ -153,8 +153,8 @@ public class TokenEndpointAuthenticationFilter implements Filter {
} }
try { try {
String grantType = request.getParameter("grant_type"); String grantType = request.getParameter(OAuth2Constants.PARAMETER.GRANT_TYPE);
if (grantType != null && grantType.equals("password")) { if (grantType != null && grantType.equals(OAuth2Constants.PARAMETER.GRANT_TYPE_PASSWORD)) {
usernamepassword(request,response); usernamepassword(request,response);
}else { }else {
Authentication authentication=ClientCredentials(request,response); Authentication authentication=ClientCredentials(request,response);
@@ -198,8 +198,8 @@ public class TokenEndpointAuthenticationFilter implements Filter {
Authentication authResult = authenticationManager.authenticate(credentials); Authentication authResult = authenticationManager.authenticate(credentials);
logger.debug("Authentication success: " + authResult.getName()); logger.debug("Authentication success: " + authResult.getName());
String clientId = request.getParameter("client_id"); String clientId = request.getParameter(OAuth2Constants.PARAMETER.CLIENT_ID);
String clientSecret = request.getParameter("client_secret"); String clientSecret = request.getParameter(OAuth2Constants.PARAMETER.CLIENT_SECRET);
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(clientId, UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(clientId,
clientSecret); clientSecret);
Authentication clientAuth = oauth20ClientAuthenticationManager.authenticate(authRequest); Authentication clientAuth = oauth20ClientAuthenticationManager.authenticate(authRequest);
@@ -245,8 +245,8 @@ public class TokenEndpointAuthenticationFilter implements Filter {
throw new HttpRequestMethodNotSupportedException(request.getMethod(), new String[] { "POST" }); throw new HttpRequestMethodNotSupportedException(request.getMethod(), new String[] { "POST" });
} }
String clientId = request.getParameter("client_id"); String clientId = request.getParameter(OAuth2Constants.PARAMETER.CLIENT_ID);
String clientSecret = request.getParameter("client_secret"); String clientSecret = request.getParameter(OAuth2Constants.PARAMETER.CLIENT_SECRET);
if(clientId == null) { if(clientId == null) {
//for header authorization basic //for header authorization basic
String authorization_bearer =request.getHeader("authorization"); String authorization_bearer =request.getHeader("authorization");
@@ -305,8 +305,8 @@ public class TokenEndpointAuthenticationFilter implements Filter {
* @return an authentication for validation (or null if there is no further authentication) * @return an authentication for validation (or null if there is no further authentication)
*/ */
protected Authentication extractCredentials(HttpServletRequest request) { protected Authentication extractCredentials(HttpServletRequest request) {
String grantType = request.getParameter("grant_type"); String grantType = request.getParameter(OAuth2Constants.PARAMETER.GRANT_TYPE);
if (grantType != null && grantType.equals("password")) { if (grantType != null && grantType.equals(OAuth2Constants.PARAMETER.GRANT_TYPE_PASSWORD)) {
UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken( UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(
request.getParameter("username"), request.getParameter("password")); request.getParameter("username"), request.getParameter("password"));
result.setDetails(authenticationDetailsSource.buildDetails(request)); result.setDetails(authenticationDetailsSource.buildDetails(request));
@@ -316,7 +316,7 @@ public class TokenEndpointAuthenticationFilter implements Filter {
} }
private Set<String> getScope(HttpServletRequest request) { private Set<String> getScope(HttpServletRequest request) {
return OAuth2Utils.parseParameterList(request.getParameter("scope")); return OAuth2Utils.parseParameterList(request.getParameter(OAuth2Constants.PARAMETER.SCOPE));
} }
public void init(FilterConfig filterConfig) throws ServletException { public void init(FilterConfig filterConfig) throws ServletException {
@@ -346,7 +346,7 @@ public class TokenEndpointAuthenticationFilter implements Filter {
uri = uri.substring(0, pathParamIndex); uri = uri.substring(0, pathParamIndex);
} }
String clientId = request.getParameter("client_id"); String clientId = request.getParameter(OAuth2Constants.PARAMETER.CLIENT_ID);
if (clientId == null) { if (clientId == null) {
// Give basic auth a chance to work instead (it's preferred anyway) // Give basic auth a chance to work instead (it's preferred anyway)
@@ -110,6 +110,10 @@ public class DefaultAccessTokenConverter implements AccessTokenConverter {
if (clientToken.getResourceIds() != null && !clientToken.getResourceIds().isEmpty()) { if (clientToken.getResourceIds() != null && !clientToken.getResourceIds().isEmpty()) {
response.put(AUD, clientToken.getResourceIds()); response.put(AUD, clientToken.getResourceIds());
} }
//default
response.put("active", Boolean.TRUE);
return response; return response;
} }
@@ -28,7 +28,7 @@ import org.maxkey.authz.oauth2.common.OAuth2Constants;
import org.maxkey.authz.oauth2.provider.ClientDetailsService; import org.maxkey.authz.oauth2.provider.ClientDetailsService;
import org.maxkey.authz.oauth2.provider.OAuth2UserDetailsService; import org.maxkey.authz.oauth2.provider.OAuth2UserDetailsService;
import org.maxkey.authz.oauth2.provider.approval.TokenApprovalStore; import org.maxkey.authz.oauth2.provider.approval.TokenApprovalStore;
import org.maxkey.authz.oauth2.provider.approval.controller.OAuth20UserApprovalHandler; import org.maxkey.authz.oauth2.provider.approval.endpoint.OAuth20UserApprovalHandler;
import org.maxkey.authz.oauth2.provider.client.ClientDetailsUserDetailsService; import org.maxkey.authz.oauth2.provider.client.ClientDetailsUserDetailsService;
import org.maxkey.authz.oauth2.provider.client.JdbcClientDetailsService; import org.maxkey.authz.oauth2.provider.client.JdbcClientDetailsService;
import org.maxkey.authz.oauth2.provider.code.AuthorizationCodeServices; import org.maxkey.authz.oauth2.provider.code.AuthorizationCodeServices;