| 1 | /*
|
|---|
| 2 | * Copyright (c) 2009 Matthias Kaeppler Licensed under the Apache License,
|
|---|
| 3 | * Version 2.0 (the "License"); you may not use this file except in compliance
|
|---|
| 4 | * with the License. You may obtain a copy of the License at
|
|---|
| 5 | * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
|
|---|
| 6 | * or agreed to in writing, software distributed under the License is
|
|---|
| 7 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|---|
| 8 | * KIND, either express or implied. See the License for the specific language
|
|---|
| 9 | * governing permissions and limitations under the License.
|
|---|
| 10 | */
|
|---|
| 11 | package oauth.signpost.signature;
|
|---|
| 12 |
|
|---|
| 13 | import java.io.IOException;
|
|---|
| 14 | import java.net.URI;
|
|---|
| 15 | import java.net.URISyntaxException;
|
|---|
| 16 | import java.util.Iterator;
|
|---|
| 17 |
|
|---|
| 18 | import oauth.signpost.OAuth;
|
|---|
| 19 | import oauth.signpost.exception.OAuthMessageSignerException;
|
|---|
| 20 | import oauth.signpost.http.HttpRequest;
|
|---|
| 21 | import oauth.signpost.http.HttpParameters;
|
|---|
| 22 |
|
|---|
| 23 | public class SignatureBaseString {
|
|---|
| 24 |
|
|---|
| 25 | private HttpRequest request;
|
|---|
| 26 |
|
|---|
| 27 | private HttpParameters requestParameters;
|
|---|
| 28 |
|
|---|
| 29 | /**
|
|---|
| 30 | * Constructs a new SBS instance that will operate on the given request
|
|---|
| 31 | * object and parameter set.
|
|---|
| 32 | *
|
|---|
| 33 | * @param request
|
|---|
| 34 | * the HTTP request
|
|---|
| 35 | * @param requestParameters
|
|---|
| 36 | * the set of request parameters from the Authorization header, query
|
|---|
| 37 | * string and form body
|
|---|
| 38 | */
|
|---|
| 39 | public SignatureBaseString(HttpRequest request, HttpParameters requestParameters) {
|
|---|
| 40 | this.request = request;
|
|---|
| 41 | this.requestParameters = requestParameters;
|
|---|
| 42 | }
|
|---|
| 43 |
|
|---|
| 44 | /**
|
|---|
| 45 | * Builds the signature base string from the data this instance was
|
|---|
| 46 | * configured with.
|
|---|
| 47 | *
|
|---|
| 48 | * @return the signature base string
|
|---|
| 49 | * @throws OAuthMessageSignerException
|
|---|
| 50 | */
|
|---|
| 51 | public String generate() throws OAuthMessageSignerException {
|
|---|
| 52 |
|
|---|
| 53 | try {
|
|---|
| 54 | String normalizedUrl = normalizeRequestUrl();
|
|---|
| 55 | String normalizedParams = normalizeRequestParameters();
|
|---|
| 56 |
|
|---|
| 57 | return request.getMethod() + '&' + OAuth.percentEncode(normalizedUrl) + '&'
|
|---|
| 58 | + OAuth.percentEncode(normalizedParams);
|
|---|
| 59 | } catch (Exception e) {
|
|---|
| 60 | throw new OAuthMessageSignerException(e);
|
|---|
| 61 | }
|
|---|
| 62 | }
|
|---|
| 63 |
|
|---|
| 64 | public String normalizeRequestUrl() throws URISyntaxException {
|
|---|
| 65 | URI uri = new URI(request.getRequestUrl());
|
|---|
| 66 | String scheme = uri.getScheme().toLowerCase();
|
|---|
| 67 | String authority = uri.getAuthority().toLowerCase();
|
|---|
| 68 | boolean dropPort = (scheme.equals("http") && uri.getPort() == 80)
|
|---|
| 69 | || (scheme.equals("https") && uri.getPort() == 443);
|
|---|
| 70 | if (dropPort) {
|
|---|
| 71 | // find the last : in the authority
|
|---|
| 72 | int index = authority.lastIndexOf(":");
|
|---|
| 73 | if (index >= 0) {
|
|---|
| 74 | authority = authority.substring(0, index);
|
|---|
| 75 | }
|
|---|
| 76 | }
|
|---|
| 77 | String path = uri.getRawPath();
|
|---|
| 78 | if (path == null || path.length() <= 0) {
|
|---|
| 79 | path = "/"; // conforms to RFC 2616 section 3.2.2
|
|---|
| 80 | }
|
|---|
| 81 | // we know that there is no query and no fragment here.
|
|---|
| 82 | return scheme + "://" + authority + path;
|
|---|
| 83 | }
|
|---|
| 84 |
|
|---|
| 85 | /**
|
|---|
| 86 | * Normalizes the set of request parameters this instance was configured
|
|---|
| 87 | * with, as per OAuth spec section 9.1.1.
|
|---|
| 88 | *
|
|---|
| 89 | * @param parameters
|
|---|
| 90 | * the set of request parameters
|
|---|
| 91 | * @return the normalized params string
|
|---|
| 92 | * @throws IOException
|
|---|
| 93 | */
|
|---|
| 94 | public String normalizeRequestParameters() throws IOException {
|
|---|
| 95 | if (requestParameters == null) {
|
|---|
| 96 | return "";
|
|---|
| 97 | }
|
|---|
| 98 |
|
|---|
| 99 | StringBuilder sb = new StringBuilder();
|
|---|
| 100 | Iterator<String> iter = requestParameters.keySet().iterator();
|
|---|
| 101 |
|
|---|
| 102 | for (int i = 0; iter.hasNext(); i++) {
|
|---|
| 103 | String param = iter.next();
|
|---|
| 104 |
|
|---|
| 105 | if (OAuth.OAUTH_SIGNATURE.equals(param) || "realm".equals(param)) {
|
|---|
| 106 | continue;
|
|---|
| 107 | }
|
|---|
| 108 |
|
|---|
| 109 | if (i > 0) {
|
|---|
| 110 | sb.append("&");
|
|---|
| 111 | }
|
|---|
| 112 |
|
|---|
| 113 | sb.append(requestParameters.getAsQueryString(param));
|
|---|
| 114 | }
|
|---|
| 115 | return sb.toString();
|
|---|
| 116 | }
|
|---|
| 117 | }
|
|---|