OAuth 2 Password Fix

This commit is contained in:
Crystal.Sea
2020-09-16 07:56:27 +08:00
parent 3fff38480b
commit edd4ad7252
12 changed files with 138 additions and 55 deletions

View File

@@ -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));
}
}

View File

@@ -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");
}
}
}

View File

@@ -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");

View File

@@ -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.");

View File

@@ -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) {