1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.security.oauth2.provider.code;
18
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import org.springframework.security.core.Authentication;
23 import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
24 import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
25 import org.springframework.security.oauth2.common.exceptions.InvalidRequestException;
26 import org.springframework.security.oauth2.common.exceptions.RedirectMismatchException;
27 import org.springframework.security.oauth2.common.util.OAuth2Utils;
28 import org.springframework.security.oauth2.provider.ClientDetails;
29 import org.springframework.security.oauth2.provider.ClientDetailsService;
30 import org.springframework.security.oauth2.provider.OAuth2Authentication;
31 import org.springframework.security.oauth2.provider.OAuth2Request;
32 import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
33 import org.springframework.security.oauth2.provider.TokenRequest;
34 import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
35 import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
36
37
38
39
40
41
42
43 public class AuthorizationCodeTokenGranter extends AbstractTokenGranter {
44
45 private static final String GRANT_TYPE = "authorization_code";
46
47 private final AuthorizationCodeServices authorizationCodeServices;
48
49 public AuthorizationCodeTokenGranter(AuthorizationServerTokenServices tokenServices,
50 AuthorizationCodeServices authorizationCodeServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) {
51 this(tokenServices, authorizationCodeServices, clientDetailsService, requestFactory, GRANT_TYPE);
52 }
53
54 protected AuthorizationCodeTokenGranter(AuthorizationServerTokenServices tokenServices, AuthorizationCodeServices authorizationCodeServices,
55 ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) {
56 super(tokenServices, clientDetailsService, requestFactory, grantType);
57 this.authorizationCodeServices = authorizationCodeServices;
58 }
59
60 @Override
61 protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
62
63 Map<String, String> parameters = tokenRequest.getRequestParameters();
64 String authorizationCode = parameters.get("code");
65 String redirectUri = parameters.get(OAuth2Utils.REDIRECT_URI);
66
67 if (authorizationCode == null) {
68 throw new InvalidRequestException("An authorization code must be supplied.");
69 }
70
71 OAuth2Authentication storedAuth = authorizationCodeServices.consumeAuthorizationCode(authorizationCode);
72 if (storedAuth == null) {
73 throw new InvalidGrantException("Invalid authorization code: " + authorizationCode);
74 }
75
76 OAuth2Request pendingOAuth2Request = storedAuth.getOAuth2Request();
77
78
79 String redirectUriApprovalParameter = pendingOAuth2Request.getRequestParameters().get(
80 OAuth2Utils.REDIRECT_URI);
81
82 if ((redirectUri != null || redirectUriApprovalParameter != null)
83 && !pendingOAuth2Request.getRedirectUri().equals(redirectUri)) {
84 throw new RedirectMismatchException("Redirect URI mismatch.");
85 }
86
87 String pendingClientId = pendingOAuth2Request.getClientId();
88 String clientId = tokenRequest.getClientId();
89 if (clientId != null && !clientId.equals(pendingClientId)) {
90
91 throw new InvalidClientException("Client ID mismatch");
92 }
93
94
95
96
97
98 Map<String, String> combinedParameters = new HashMap<String, String>(pendingOAuth2Request
99 .getRequestParameters());
100
101 combinedParameters.putAll(parameters);
102
103
104 OAuth2Request finalStoredOAuth2Request = pendingOAuth2Request.createOAuth2Request(combinedParameters);
105
106 Authentication userAuth = storedAuth.getUserAuthentication();
107
108 return new OAuth2Authentication(finalStoredOAuth2Request, userAuth);
109
110 }
111
112 }