View Javadoc
1   /*
2    * Copyright 2002-2011 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.security.oauth2.provider.password;
18  
19  import java.util.LinkedHashMap;
20  import java.util.Map;
21  
22  import org.springframework.security.authentication.AbstractAuthenticationToken;
23  import org.springframework.security.authentication.AccountStatusException;
24  import org.springframework.security.authentication.AuthenticationManager;
25  import org.springframework.security.authentication.BadCredentialsException;
26  import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
27  import org.springframework.security.core.Authentication;
28  import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
29  import org.springframework.security.oauth2.provider.ClientDetails;
30  import org.springframework.security.oauth2.provider.ClientDetailsService;
31  import org.springframework.security.oauth2.provider.OAuth2Authentication;
32  import org.springframework.security.oauth2.provider.OAuth2Request;
33  import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
34  import org.springframework.security.oauth2.provider.TokenRequest;
35  import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
36  import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
37  
38  /**
39   * @author Dave Syer
40   * 
41   */
42  public class ResourceOwnerPasswordTokenGranter extends AbstractTokenGranter {
43  
44  	private static final String GRANT_TYPE = "password";
45  
46  	private final AuthenticationManager authenticationManager;
47  
48  	public ResourceOwnerPasswordTokenGranter(AuthenticationManager authenticationManager,
49  			AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) {
50  		this(authenticationManager, tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
51  	}
52  
53  	protected ResourceOwnerPasswordTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices,
54  			ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) {
55  		super(tokenServices, clientDetailsService, requestFactory, grantType);
56  		this.authenticationManager = authenticationManager;
57  	}
58  
59  	@Override
60  	protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
61  
62  		Map<String, String> parameters = new LinkedHashMap<String, String>(tokenRequest.getRequestParameters());
63  		String username = parameters.get("username");
64  		String password = parameters.get("password");
65  		// Protect from downstream leaks of password
66  		parameters.remove("password");
67  
68  		Authentication userAuth = new UsernamePasswordAuthenticationToken(username, password);
69  		((AbstractAuthenticationToken) userAuth).setDetails(parameters);
70  		try {
71  			userAuth = authenticationManager.authenticate(userAuth);
72  		}
73  		catch (AccountStatusException ase) {
74  			//covers expired, locked, disabled cases (mentioned in section 5.2, draft 31)
75  			throw new InvalidGrantException(ase.getMessage());
76  		}
77  		catch (BadCredentialsException e) {
78  			// If the username/password are wrong the spec says we should send 400/invalid grant
79  			throw new InvalidGrantException(e.getMessage());
80  		}
81  		if (userAuth == null || !userAuth.isAuthenticated()) {
82  			throw new InvalidGrantException("Could not authenticate user: " + username);
83  		}
84  		
85  		OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);		
86  		return new OAuth2Authentication(storedOAuth2Request, userAuth);
87  	}
88  }