From edd4ad72520f89ec83890b13c9ca504b616f52f0 Mon Sep 17 00:00:00 2001 From: "Crystal.Sea" Date: Wed, 16 Sep 2020 07:56:27 +0800 Subject: [PATCH] OAuth 2 Password Fix --- .../authn/AbstractAuthenticationProvider.java | 2 +- .../cas/endpoint/Cas10AuthorizeEndpoint.java | 2 +- .../cas/endpoint/Cas20AuthorizeEndpoint.java | 2 +- .../cas/endpoint/Cas30AuthorizeEndpoint.java | 2 +- .../cas/endpoint/CasAuthorizeEndpoint.java | 2 +- .../provider/OAuth2UserDetailsService.java | 49 +++++++++++++ .../client/JdbcClientDetailsService.java | 6 +- .../provider/endpoint/AbstractEndpoint.java | 13 +++- .../provider/endpoint/TokenEndpoint.java | 14 ++-- .../TokenEndpointAuthenticationFilter.java | 19 +++-- .../main/java/org/maxkey/MaxKeyConfig.java | 13 +--- .../Oauth20AutoConfiguration.java | 69 +++++++++++++------ 12 files changed, 138 insertions(+), 55 deletions(-) create mode 100644 maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/OAuth2UserDetailsService.java diff --git a/maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java b/maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java index 2604ba11a..0138c10ea 100644 --- a/maxkey-core/src/main/java/org/maxkey/authn/AbstractAuthenticationProvider.java +++ b/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) { diff --git a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas10AuthorizeEndpoint.java b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas10AuthorizeEndpoint.java index b71afd537..00fc8d606 100644 --- a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas10AuthorizeEndpoint.java +++ b/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{ diff --git a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas20AuthorizeEndpoint.java b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas20AuthorizeEndpoint.java index 371b51c02..1a8a3f40c 100644 --- a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas20AuthorizeEndpoint.java +++ b/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{ diff --git a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas30AuthorizeEndpoint.java b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas30AuthorizeEndpoint.java index 53173ad59..6bb2dda98 100644 --- a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/Cas30AuthorizeEndpoint.java +++ b/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{ diff --git a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/CasAuthorizeEndpoint.java b/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/CasAuthorizeEndpoint.java index a419ece26..8390b702a 100644 --- a/maxkey-protocols/maxkey-protocol-cas/src/main/java/org/maxkey/authz/cas/endpoint/CasAuthorizeEndpoint.java +++ b/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{ diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/OAuth2UserDetailsService.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/OAuth2UserDetailsService.java new file mode 100644 index 000000000..8c920347a --- /dev/null +++ b/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)); + } + +} diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/client/JdbcClientDetailsService.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/client/JdbcClientDetailsService.java index 350f2c3f8..7d823d2da 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/client/JdbcClientDetailsService.java +++ b/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"); } } - + } diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/AbstractEndpoint.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/AbstractEndpoint.java index e0a263226..2c9221f2c 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/AbstractEndpoint.java +++ b/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"); diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpoint.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpoint.java index fe4f4f2b3..af9084427 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpoint.java +++ b/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 postAccessToken(@RequestParam Map 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."); diff --git a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java b/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java index f2e37cab9..4d0273fa4 100644 --- a/maxkey-protocols/maxkey-protocol-oauth-2.0/src/main/java/org/maxkey/authz/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java +++ b/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 getSingleValueMap(HttpServletRequest request) { diff --git a/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyConfig.java b/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyConfig.java index 9ba4e9681..be5768e47 100644 --- a/maxkey-web-maxkey/src/main/java/org/maxkey/MaxKeyConfig.java +++ b/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() { - _logger.debug("TokenEndpointAuthenticationFilter init "); - FilterRegistrationBean registration = new FilterRegistrationBean(); - 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}") diff --git a/maxkey-web-maxkey/src/main/java/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java b/maxkey-web-maxkey/src/main/java/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java index cbd4c78e6..8652cf34b 100644 --- a/maxkey-web-maxkey/src/main/java/org/maxkey/autoconfigure/Oauth20AutoConfiguration.java +++ b/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 TokenEndpointAuthenticationFilter() { + _logger.debug("TokenEndpointAuthenticationFilter init "); + FilterRegistrationBean registration = new FilterRegistrationBean(); + 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. @@ -332,20 +333,44 @@ public class Oauth20AutoConfiguration implements InitializingBean { return userApprovalHandler; } + /** + * 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; }