فهرست منبع

OAuth 2 Password Fix

Crystal.Sea 4 سال پیش
والد
کامیت
edd4ad7252
12فایلهای تغییر یافته به همراه138 افزوده شده و 55 حذف شده
  1. 1 1
      maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java
  2. 1 1
      maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas10AuthorizeEndpoint.java
  3. 1 1
      maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas20AuthorizeEndpoint.java
  4. 1 1
      maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas30AuthorizeEndpoint.java
  5. 1 1
      maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/CasAuthorizeEndpoint.java
  6. 49 0
      maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/OAuth2UserDetailsService.java
  7. 3 3
      maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/client/JdbcClientDetailsService.java
  8. 10 3
      maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/AbstractEndpoint.java
  9. 9 5
      maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpoint.java
  10. 14 5
      maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java
  11. 1 12
      maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyConfig.java
  12. 47 22
      maxkey-web-maxkey/src/main/java/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java

+ 1 - 1
maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java

@@ -242,7 +242,7 @@ public abstract class AbstractAuthenticationProvider {
      * @param password String
      * @return
      */
-    protected UserInfo loadUserInfo(String username, String password) {
+    public UserInfo loadUserInfo(String username, String password) {
         UserInfo userInfo = authenticationRealm.loadUserInfo(username, password);
 
         if (userInfo != null) {

+ 1 - 1
maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas10AuthorizeEndpoint.java

@@ -36,7 +36,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
 
 /**
  * @author Crystal.Sea
- * https://apereo.github.io/cas/5.0.x/protocol/CAS-Protocol-V2-Specification.html
+ * https://apereo.github.io/cas/6.2.x/protocol/CAS-Protocol-Specification.html
  */
 @Controller
 public class Cas10AuthorizeEndpoint   extends CasBaseAuthorizeEndpoint{

+ 1 - 1
maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas20AuthorizeEndpoint.java

@@ -41,7 +41,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
 
 /**
  * @author Crystal.Sea
- * https://apereo.github.io/cas/5.0.x/protocol/CAS-Protocol-V2-Specification.html
+ * https://apereo.github.io/cas/6.2.x/protocol/CAS-Protocol-V2-Specification.html
  */
 @Controller
 public class Cas20AuthorizeEndpoint  extends CasBaseAuthorizeEndpoint{

+ 1 - 1
maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas30AuthorizeEndpoint.java

@@ -40,7 +40,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
 
 /**
  * @author Crystal.Sea
- * https://apereo.github.io/cas/5.0.x/protocol/CAS-Protocol.html
+ * https://apereo.github.io/cas/6.2.x/protocol/CAS-Protocol-Specification.html
  */
 @Controller
 public class Cas30AuthorizeEndpoint  extends CasBaseAuthorizeEndpoint{

+ 1 - 1
maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/CasAuthorizeEndpoint.java

@@ -41,7 +41,7 @@ import org.springframework.web.servlet.ModelAndView;
 
 /**
  * @author Crystal.Sea
- * https://apereo.github.io/cas/5.0.x/protocol/CAS-Protocol-V2-Specification.html
+ * https://apereo.github.io/cas/6.2.x/protocol/CAS-Protocol.html
  */
 @Controller
 public class CasAuthorizeEndpoint  extends CasBaseAuthorizeEndpoint{

+ 49 - 0
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/OAuth2UserDetailsService.java

@@ -0,0 +1,49 @@
+/*
+ * Copyright 2006-2011 the original author or authors.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.maxkey.authz.oauth2.provider;
+
+import org.maxkey.domain.UserInfo;
+import org.maxkey.persistence.db.LoginService;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+
+/**
+ * @author Dave Syer
+ * 
+ */
+public class OAuth2UserDetailsService implements UserDetailsService {
+
+	
+    LoginService loginService;
+	
+
+	public void setLoginService(LoginService loginService) {
+        this.loginService = loginService;
+    }
+
+
+    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+		UserInfo userInfo;
+		try {
+		    userInfo = loginService.loadUserInfo(username, "");
+		} catch (NoSuchClientException e) {
+			throw new UsernameNotFoundException(e.getMessage(), e);
+		}
+		
+		
+		return new User(username, userInfo.getPassword(), loginService.grantAuthority(userInfo));
+	}
+
+}

+ 3 - 3
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/client/JdbcClientDetailsService.java

@@ -34,6 +34,7 @@ import org.maxkey.authz.oauth2.provider.ClientAlreadyExistsException;
 import org.maxkey.authz.oauth2.provider.ClientDetailsService;
 import org.maxkey.authz.oauth2.provider.ClientRegistrationService;
 import org.maxkey.authz.oauth2.provider.NoSuchClientException;
+import org.maxkey.crypto.password.NoOpPasswordEncoder;
 import org.maxkey.domain.apps.oauth2.provider.ClientDetails;
 import org.maxkey.domain.apps.oauth2.provider.client.BaseClientDetails;
 import org.springframework.dao.DuplicateKeyException;
@@ -41,7 +42,6 @@ import org.springframework.dao.EmptyResultDataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.core.RowMapper;
 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
-import org.springframework.security.crypto.password.NoOpPasswordEncoder;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.util.Assert;
 import org.springframework.util.ClassUtils;
@@ -50,7 +50,7 @@ import org.springframework.util.StringUtils;
 /**
  * Basic, JDBC implementation of the client details service.
  */
-public class JdbcClientDetailsService implements ClientDetailsService, ClientRegistrationService {
+public class JdbcClientDetailsService implements ClientDetailsService, ClientRegistrationService{
 
     private static final Log logger = LogFactory.getLog(JdbcClientDetailsService.class);
 
@@ -338,5 +338,5 @@ public class JdbcClientDetailsService implements ClientDetailsService, ClientReg
                     "Neither Jackson 1 nor 2 is available so JSON conversion cannot be done");
         }
     }
-
+    
 }

+ 10 - 3
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/AbstractEndpoint.java

@@ -30,12 +30,14 @@ import org.maxkey.authz.oauth2.provider.code.AuthorizationCodeServices;
 import org.maxkey.authz.oauth2.provider.code.AuthorizationCodeTokenGranter;
 import org.maxkey.authz.oauth2.provider.code.InMemoryAuthorizationCodeServices;
 import org.maxkey.authz.oauth2.provider.implicit.ImplicitTokenGranter;
+import org.maxkey.authz.oauth2.provider.password.ResourceOwnerPasswordTokenGranter;
 import org.maxkey.authz.oauth2.provider.refresh.RefreshTokenGranter;
 import org.maxkey.authz.oauth2.provider.request.DefaultOAuth2RequestFactory;
 import org.maxkey.authz.oauth2.provider.token.AuthorizationServerTokenServices;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.util.Assert;
 
 /**
@@ -67,6 +69,11 @@ public class AbstractEndpoint implements InitializingBean {
   	@Qualifier("oAuth2RequestFactory")
 	private OAuth2RequestFactory defaultOAuth2RequestFactory;
 
+	@Autowired
+    @Qualifier("oauth20UserAuthenticationManager")
+	AuthenticationManager authenticationManager;
+	
+	
 	public void afterPropertiesSet() throws Exception {
 		if (tokenGranter == null) {
 			//ClientDetailsService clientDetails = clientDetailsService();
@@ -81,10 +88,10 @@ public class AbstractEndpoint implements InitializingBean {
 			ImplicitTokenGranter implicit = new ImplicitTokenGranter(tokenServices, clientDetailsService, oAuth2RequestFactory);
 			tokenGranters.add(implicit);
 			tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetailsService, oAuth2RequestFactory));
-			/*if (authenticationManager != null) {
+			if (authenticationManager != null) {
 				tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices,
-						clientDetails, requestFactory));
-			}*/
+				        clientDetailsService, oAuth2RequestFactory));
+			}
 			tokenGranter = new CompositeTokenGranter(tokenGranters);
 		}
 		Assert.state(tokenGranter != null, "TokenGranter must be provided");

+ 9 - 5
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpoint.java

@@ -95,14 +95,18 @@ public class TokenEndpoint extends AbstractEndpoint {
 	public ResponseEntity<OAuth2AccessToken> postAccessToken(@RequestParam
 	Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
 		// TokenEndpointAuthenticationFilter
-		Principal principal=(Principal)WebContext.getAuthentication().getPrincipal();
-		
+	    
+	    Object principal = WebContext.getAuthentication();
+
+		if(parameters.get("code") != null) {
+		    principal=WebContext.getAuthentication().getPrincipal();
+		}
 		if (!(principal instanceof Authentication)) {
 			throw new InsufficientAuthenticationException(
 					"There is no client authentication. Try adding an appropriate authentication filter.");
 		}
 
-		String clientId = getClientId(principal);
+		String clientId = getClientId((Authentication)principal);
 		ClientDetails authenticatedClient = getClientDetailsService().loadClientByClientId(clientId);
 
 		TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(parameters, authenticatedClient);
@@ -138,7 +142,7 @@ public class TokenEndpoint extends AbstractEndpoint {
 		/**crystal.sea
 		 * code must uuid format
 		 */
-		 if (!StringGenerator.uuidMatches(parameters.get("code"))) {
+		 if (parameters.get("code") != null &&!StringGenerator.uuidMatches(parameters.get("code"))) {
 		    	throw new InvalidRequestException("The code is not valid format .");
 		}
 		 
@@ -160,7 +164,7 @@ public class TokenEndpoint extends AbstractEndpoint {
 	 * @param principal the currently authentication principal
 	 * @return a client id if there is one in the principal
 	 */
-	protected String getClientId(Principal principal) {
+	protected String getClientId(Authentication principal) {
 		Authentication client = (Authentication) principal;
 		if (!client.isAuthenticated()) {
 			throw new InsufficientAuthenticationException("The client is not authenticated.");

+ 14 - 5
maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java

@@ -84,6 +84,8 @@ public class TokenEndpointAuthenticationFilter implements Filter {
 	
 	private  AuthenticationManager authenticationManager;
 	
+	private AuthenticationManager  oauth20ClientAuthenticationManager;
+	
 	private  OAuth2RequestFactory oAuth2RequestFactory;
 
 	public TokenEndpointAuthenticationFilter() {
@@ -115,11 +117,14 @@ public class TokenEndpointAuthenticationFilter implements Filter {
 			ServletException {
 		logger.debug("Authentication TokenEndpoint ");
 		if(authenticationManager==null) {
-			authenticationManager=(AuthenticationManager)WebContext.getBean("oauth20ClientAuthenticationManager");
+			authenticationManager=(AuthenticationManager)WebContext.getBean("oauth20UserAuthenticationManager");
 		}
 		if(oAuth2RequestFactory==null) {
 			oAuth2RequestFactory=(OAuth2RequestFactory)WebContext.getBean("oAuth2RequestFactory");
 		}
+		if(oauth20ClientAuthenticationManager==null) {
+		    oauth20ClientAuthenticationManager = (AuthenticationManager)WebContext.getBean("oauth20ClientAuthenticationManager");
+		}
 		
 		final boolean debug = logger.isDebugEnabled();
 		final HttpServletRequest request = (HttpServletRequest) req;
@@ -133,7 +138,7 @@ public class TokenEndpointAuthenticationFilter implements Filter {
 				Authentication authentication=ClientCredentials(request,response);
 				BasicAuthentication auth =new BasicAuthentication();
 				auth.setUsername(((User)authentication.getPrincipal()).getUsername());
-				 auth.setAuthenticated(true);
+				auth.setAuthenticated(true);
 				UsernamePasswordAuthenticationToken simpleUserAuthentication = new UsernamePasswordAuthenticationToken(auth, authentication.getCredentials(), authentication.getAuthorities());
 				WebContext.setAuthentication(simpleUserAuthentication);
 			}
@@ -166,8 +171,12 @@ public class TokenEndpointAuthenticationFilter implements Filter {
 			Authentication authResult = authenticationManager.authenticate(credentials);
 	
 			logger.debug("Authentication success: " + authResult.getName());
-	
-			Authentication clientAuth = SecurityContextHolder.getContext().getAuthentication();
+			String clientId = request.getParameter("client_id");
+	        String clientSecret = request.getParameter("client_secret");
+	        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(clientId,
+	                clientSecret);
+	        Authentication clientAuth = oauth20ClientAuthenticationManager.authenticate(authRequest);
+			//Authentication clientAuth = SecurityContextHolder.getContext().getAuthentication();
 			if (clientAuth == null) {
 				throw new BadCredentialsException(
 						"No client authentication found. Remember to put a filter upstream of the TokenEndpointAuthenticationFilter.");
@@ -231,7 +240,7 @@ public class TokenEndpointAuthenticationFilter implements Filter {
 			clientId = clientId.trim();
 			UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(clientId,clientSecret);
 
-			return this.authenticationManager.authenticate(authRequest);
+			return this.oauth20ClientAuthenticationManager.authenticate(authRequest);
 		}
 	 
 	private Map<String, String> getSingleValueMap(HttpServletRequest request) {

+ 1 - 12
maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyConfig.java

@@ -27,7 +27,6 @@ import org.maxkey.authn.realm.activedirectory.ActiveDirectoryAuthenticationRealm
 import org.maxkey.authn.realm.activedirectory.ActiveDirectoryServer;
 import org.maxkey.authn.support.kerberos.KerberosProxy;
 import org.maxkey.authn.support.kerberos.RemoteKerberosService;
-import org.maxkey.authz.oauth2.provider.endpoint.TokenEndpointAuthenticationFilter;
 import org.maxkey.constants.ConstantsProperties;
 import org.maxkey.crypto.password.opt.AbstractOptAuthn;
 import org.maxkey.crypto.password.opt.algorithm.KeyUriFormat;
@@ -79,17 +78,7 @@ import org.springframework.jdbc.core.JdbcTemplate;
 public class MaxKeyConfig  implements InitializingBean {
     private static final  Logger _logger = LoggerFactory.getLogger(MaxKeyConfig.class);
     
-    @Bean
-    public FilterRegistrationBean<TokenEndpointAuthenticationFilter> TokenEndpointAuthenticationFilter() {
-        _logger.debug("TokenEndpointAuthenticationFilter init ");
-        FilterRegistrationBean<TokenEndpointAuthenticationFilter> registration = new FilterRegistrationBean<TokenEndpointAuthenticationFilter>();
-        registration.setFilter(new TokenEndpointAuthenticationFilter());
-        registration.addUrlPatterns("/oauth/v20/token/*");
-        registration.setName("TokenEndpointAuthenticationFilter");
-        registration.setOrder(1);
-        return registration;
-    }
-   
+
     @Bean(name = "keyUriFormat")
     public KeyUriFormat keyUriFormat(
             @Value("${config.otp.keyuri.format.type:totp}")

+ 47 - 22
maxkey-web-maxkey/src/main/java/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java

@@ -21,11 +21,13 @@ import java.net.URI;
 import java.security.NoSuchAlgorithmException;
 import java.security.spec.InvalidKeySpecException;
 
+import javax.servlet.Filter;
 import javax.sql.DataSource;
 
 import org.maxkey.authn.AbstractAuthenticationProvider;
 import org.maxkey.authn.support.jwt.JwtLoginService;
 import org.maxkey.authz.oauth2.provider.ClientDetailsService;
+import org.maxkey.authz.oauth2.provider.OAuth2UserDetailsService;
 import org.maxkey.authz.oauth2.provider.approval.TokenApprovalStore;
 import org.maxkey.authz.oauth2.provider.approval.controller.OAuth20UserApprovalHandler;
 import org.maxkey.authz.oauth2.provider.client.ClientDetailsUserDetailsService;
@@ -34,6 +36,7 @@ import org.maxkey.authz.oauth2.provider.code.AuthorizationCodeServices;
 import org.maxkey.authz.oauth2.provider.code.InMemoryAuthorizationCodeServices;
 import org.maxkey.authz.oauth2.provider.code.JdbcAuthorizationCodeServices;
 import org.maxkey.authz.oauth2.provider.code.RedisAuthorizationCodeServices;
+import org.maxkey.authz.oauth2.provider.endpoint.TokenEndpointAuthenticationFilter;
 import org.maxkey.authz.oauth2.provider.request.DefaultOAuth2RequestFactory;
 import org.maxkey.authz.oauth2.provider.token.TokenStore;
 import org.maxkey.authz.oauth2.provider.token.DefaultTokenServices;
@@ -47,12 +50,13 @@ import org.maxkey.constants.ConstantsProperties;
 import org.maxkey.crypto.jose.keystore.JWKSetKeyStore;
 import org.maxkey.crypto.jwt.encryption.service.impl.DefaultJwtEncryptionAndDecryptionService;
 import org.maxkey.crypto.jwt.signer.service.impl.DefaultJwtSigningAndValidationService;
-import org.maxkey.crypto.password.NoOpPasswordEncoder;
+import org.maxkey.persistence.db.LoginService;
 import org.maxkey.persistence.redis.RedisConnectionFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
@@ -77,6 +81,17 @@ import com.nimbusds.jose.JWEAlgorithm;
 public class Oauth20AutoConfiguration implements InitializingBean {
     private static final  Logger _logger = LoggerFactory.getLogger(Oauth20AutoConfiguration.class);
     
+    @Bean
+    public FilterRegistrationBean<Filter> TokenEndpointAuthenticationFilter() {
+        _logger.debug("TokenEndpointAuthenticationFilter init ");
+        FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<Filter>();
+        registration.setFilter(new TokenEndpointAuthenticationFilter());
+        registration.addUrlPatterns("/oauth/v20/token/*");
+        registration.setName("TokenEndpointAuthenticationFilter");
+        registration.setOrder(1);
+        return registration;
+    }
+    
     /**
      * OIDCProviderMetadataDetails. 
      * Self-issued Provider Metadata
@@ -256,21 +271,7 @@ public class Oauth20AutoConfiguration implements InitializingBean {
         JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
         clientDetailsService.setPasswordEncoder(passwordReciprocal);
         return clientDetailsService;
-    }
-    
-    /**
-     * clientDetailsUserDetailsService. 
-     * @return oauth20ClientDetailsUserService
-     */
-    @Bean(name = "oauth20ClientDetailsUserService")
-    public ClientDetailsUserDetailsService clientDetailsUserDetailsService(
-            JdbcClientDetailsService oauth20JdbcClientDetailsService,PasswordEncoder passwordReciprocal) {
-        ClientDetailsUserDetailsService cientDetailsUserDetailsService = 
-                new ClientDetailsUserDetailsService(oauth20JdbcClientDetailsService);
-        cientDetailsUserDetailsService.setPasswordEncoder(passwordReciprocal);
-        return cientDetailsUserDetailsService;
-    }
-    
+    }    
     
     /**
      * clientDetailsUserDetailsService. 
@@ -334,18 +335,42 @@ public class Oauth20AutoConfiguration implements InitializingBean {
     
     /**
      * ProviderManager. 
+     * @return oauth20UserAuthenticationManager
+     */
+    @Bean(name = "oauth20UserAuthenticationManager")
+    public ProviderManager oauth20UserAuthenticationManager(
+            PasswordEncoder passwordEncoder,
+            LoginService loginService
+            ) {
+        
+        OAuth2UserDetailsService userDetailsService =new OAuth2UserDetailsService();
+        userDetailsService.setLoginService(loginService);
+        
+        DaoAuthenticationProvider daoAuthenticationProvider= new DaoAuthenticationProvider();
+        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
+        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
+        ProviderManager authenticationManager = new ProviderManager(daoAuthenticationProvider);
+        return authenticationManager;
+    }
+    
+    /**
+     * ProviderManager. 
      * @return oauth20ClientAuthenticationManager
      */
     @Bean(name = "oauth20ClientAuthenticationManager")
     public ProviderManager oauth20ClientAuthenticationManager(
-            ClientDetailsUserDetailsService oauth20ClientDetailsUserService
+            JdbcClientDetailsService oauth20JdbcClientDetailsService,
+            PasswordEncoder passwordReciprocal
             ) {
+        
+        ClientDetailsUserDetailsService cientDetailsUserDetailsService = 
+                new ClientDetailsUserDetailsService(oauth20JdbcClientDetailsService);
+        
         DaoAuthenticationProvider daoAuthenticationProvider= new DaoAuthenticationProvider();
-        PasswordEncoder passwordEncoder = NoOpPasswordEncoder.getInstance();
-        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
-        daoAuthenticationProvider.setUserDetailsService(oauth20ClientDetailsUserService);
-        ProviderManager clientAuthenticationManager = new ProviderManager(daoAuthenticationProvider);
-        return clientAuthenticationManager;
+        daoAuthenticationProvider.setPasswordEncoder(passwordReciprocal);
+        daoAuthenticationProvider.setUserDetailsService(cientDetailsUserDetailsService);
+        ProviderManager authenticationManager = new ProviderManager(daoAuthenticationProvider);
+        return authenticationManager;
     }