1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.security.oauth.provider.filter;
18
19 import org.apache.commons.codec.DecoderException;
20 import static org.springframework.security.oauth.common.OAuthCodec.oauthDecode;
21 import static org.springframework.security.oauth.common.OAuthCodec.oauthEncode;
22 import org.springframework.security.oauth.common.OAuthConsumerParameter;
23 import org.springframework.security.oauth.common.StringSplitUtils;
24 import org.springframework.security.oauth.provider.OAuthProviderSupport;
25
26 import javax.servlet.http.HttpServletRequest;
27 import java.util.*;
28 import java.net.URL;
29 import java.net.MalformedURLException;
30
31
32
33
34
35
36 public class CoreOAuthProviderSupport implements OAuthProviderSupport {
37
38 private final Set<String> supportedOAuthParameters;
39 private String baseUrl = null;
40
41 public CoreOAuthProviderSupport() {
42 Set<String> supportedOAuthParameters = new TreeSet<String>();
43 for (OAuthConsumerParameter supportedParameter : OAuthConsumerParameter.values()) {
44 supportedOAuthParameters.add(supportedParameter.toString());
45 }
46 this.supportedOAuthParameters = supportedOAuthParameters;
47 }
48
49
50 public Map<String, String> parseParameters(HttpServletRequest request) {
51 Map<String, String> parameters = parseHeaderParameters(request);
52
53 if (parameters == null) {
54
55 parameters = new HashMap<String, String>();
56 for (String supportedOAuthParameter : getSupportedOAuthParameters()) {
57 String param = request.getParameter(supportedOAuthParameter);
58 if (param != null) {
59 parameters.put(supportedOAuthParameter, param);
60 }
61 }
62 }
63
64 return parameters;
65 }
66
67
68
69
70
71
72
73 protected Map<String, String> parseHeaderParameters(HttpServletRequest request) {
74 String header = null;
75 Enumeration<String> headers = request.getHeaders("Authorization");
76 while (headers.hasMoreElements()) {
77 String value = headers.nextElement();
78 if ((value.toLowerCase().startsWith("oauth "))) {
79 header = value;
80 break;
81 }
82 }
83
84 Map<String, String> parameters = null;
85 if (header != null) {
86 parameters = new HashMap<String, String>();
87 String authHeaderValue = header.substring(6);
88
89
90 String[] headerEntries = StringSplitUtils.splitIgnoringQuotes(authHeaderValue, ',');
91 for (Object o : StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, "=", "\"").entrySet()) {
92 Map.Entry entry = (Map.Entry) o;
93 try {
94 String key = oauthDecode((String) entry.getKey());
95 String value = oauthDecode((String) entry.getValue());
96 parameters.put(key, value);
97 }
98 catch (DecoderException e) {
99 throw new IllegalStateException(e);
100 }
101 }
102 }
103
104 return parameters;
105 }
106
107
108
109
110
111
112 protected Set<String> getSupportedOAuthParameters() {
113 return this.supportedOAuthParameters;
114 }
115
116
117 public String getSignatureBaseString(HttpServletRequest request) {
118 SortedMap<String, SortedSet<String>> significantParameters = loadSignificantParametersForSignatureBaseString(request);
119
120
121 StringBuilder queryString = new StringBuilder();
122 Iterator<Map.Entry<String, SortedSet<String>>> paramIt = significantParameters.entrySet().iterator();
123 while (paramIt.hasNext()) {
124 Map.Entry<String, SortedSet<String>> sortedParameter = paramIt.next();
125 Iterator<String> valueIt = sortedParameter.getValue().iterator();
126 while (valueIt.hasNext()) {
127 String parameterValue = valueIt.next();
128 queryString.append(sortedParameter.getKey()).append('=').append(parameterValue);
129 if (paramIt.hasNext() || valueIt.hasNext()) {
130 queryString.append('&');
131 }
132 }
133 }
134
135 String url = getBaseUrl(request);
136 if (url == null) {
137
138 url = request.getRequestURL().toString();
139 }
140 url = normalizeUrl(url);
141 url = oauthEncode(url);
142
143 String method = request.getMethod().toUpperCase();
144 return new StringBuilder(method).append('&').append(url).append('&').append(oauthEncode(queryString.toString())).toString();
145 }
146
147
148
149
150
151
152
153
154 protected String normalizeUrl(String url) {
155 try {
156 URL requestURL = new URL(url);
157 StringBuilder normalized = new StringBuilder(requestURL.getProtocol().toLowerCase()).append("://").append(requestURL.getHost().toLowerCase());
158 if ((requestURL.getPort() >= 0) && (requestURL.getPort() != requestURL.getDefaultPort())) {
159 normalized.append(":").append(requestURL.getPort());
160 }
161 normalized.append(requestURL.getPath());
162 return normalized.toString();
163 }
164 catch (MalformedURLException e) {
165 throw new IllegalStateException("Illegal URL for calculating the OAuth signature.", e);
166 }
167 }
168
169
170
171
172
173
174
175
176 protected SortedMap<String, SortedSet<String>> loadSignificantParametersForSignatureBaseString(HttpServletRequest request) {
177
178 SortedMap<String, SortedSet<String>> significantParameters = new TreeMap<String, SortedSet<String>>();
179
180 Enumeration parameterNames = request.getParameterNames();
181 while (parameterNames.hasMoreElements()) {
182 String parameterName = (String) parameterNames.nextElement();
183 String[] values = request.getParameterValues(parameterName);
184 if (values == null) {
185 values = new String[]{ "" };
186 }
187
188 parameterName = oauthEncode(parameterName);
189 for (String parameterValue : values) {
190 if (parameterValue == null) {
191 parameterValue = "";
192 }
193
194 parameterValue = oauthEncode(parameterValue);
195 SortedSet<String> significantValues = significantParameters.get(parameterName);
196 if (significantValues == null) {
197 significantValues = new TreeSet<String>();
198 significantParameters.put(parameterName, significantValues);
199 }
200 significantValues.add(parameterValue);
201 }
202 }
203
204
205 Map<String, String> oauthParams = parseParameters(request);
206 oauthParams.remove("realm");
207 Set<String> parsedParams = oauthParams.keySet();
208 for (String parameterName : parsedParams) {
209 String parameterValue = oauthParams.get(parameterName);
210 if (parameterValue == null) {
211 parameterValue = "";
212 }
213
214 parameterName = oauthEncode(parameterName);
215 parameterValue = oauthEncode(parameterValue);
216 SortedSet<String> significantValues = significantParameters.get(parameterName);
217 if (significantValues == null) {
218 significantValues = new TreeSet<String>();
219 significantParameters.put(parameterName, significantValues);
220 }
221 significantValues.add(parameterValue);
222 }
223
224
225 significantParameters.remove(OAuthConsumerParameter.oauth_signature.toString());
226 return significantParameters;
227 }
228
229
230
231
232
233
234
235 protected String getBaseUrl(HttpServletRequest request) {
236 String baseUrl = getBaseUrl();
237 if (baseUrl != null) {
238 StringBuilder builder = new StringBuilder(baseUrl);
239 String path = request.getRequestURI();
240 if (path != null && !"".equals(path)) {
241 if (!baseUrl.endsWith("/") && !path.startsWith("/")) {
242 builder.append('/');
243 }
244 builder.append(path);
245 }
246 baseUrl = builder.toString();
247 }
248 return baseUrl;
249 }
250
251
252
253
254
255
256 public String getBaseUrl() {
257 return baseUrl;
258 }
259
260
261
262
263
264
265 public void setBaseUrl(String baseUrl) {
266 this.baseUrl = baseUrl;
267 }
268 }