Author: ivol37 at gmail.com
Date: Wed Jan 5 09:40:13 2011
New Revision: 559
Log:
[AMDATU-222] Small improvement for base64 encoding without line feeds/cariage
returns
Modified:
trunk/amdatu-authentication/tokenprovider/src/main/java/org/amdatu/authentication/tokenprovider/service/TokenProviderImpl.java
Modified:
trunk/amdatu-authentication/tokenprovider/src/main/java/org/amdatu/authentication/tokenprovider/service/TokenProviderImpl.java
==============================================================================
---
trunk/amdatu-authentication/tokenprovider/src/main/java/org/amdatu/authentication/tokenprovider/service/TokenProviderImpl.java
(original)
+++
trunk/amdatu-authentication/tokenprovider/src/main/java/org/amdatu/authentication/tokenprovider/service/TokenProviderImpl.java
Wed Jan 5 09:40:13 2011
@@ -38,13 +38,14 @@
import org.amdatu.authentication.tokenprovider.TokenProviderException;
import org.amdatu.authentication.tokenprovider.TokenStorageProvider;
import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.binary.StringUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.osgi.service.log.LogService;
public class TokenProviderImpl implements TokenProvider {
// Name the authorization header when a token is passed in the
"Authorization" header of a HTTP request
public final static String AUTHORIZATION_HEADER = "Amdatu";
-
+
// Service dependencies
private volatile LogService m_logService;
@@ -63,7 +64,7 @@
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
* @throws NoSuchPaddingException
- * @throws UnsupportedEncodingException
+ * @throws UnsupportedEncodingException
*/
public void init() throws NoSuchAlgorithmException, InvalidKeyException,
NoSuchPaddingException, UnsupportedEncodingException {
if (m_secretKey == null) {
@@ -98,23 +99,23 @@
String signature = DigestUtils.md5Hex(signvalue);
return signature;
}
-
+
private boolean verifySignature(SortedMap<String, String> attributes,
String signature) throws TokenProviderException {
String verifySignature = generateSignature(attributes);
return signature.equals(verifySignature);
}
-
- // Converts a map of attribute keys and values into a single String
representation, using
+
+ // Converts a map of attribute keys and values into a single String
representation, using
// URL encoding
String attributesToString(SortedMap<String, String> attributes) throws
UnsupportedEncodingException {
StringBuffer result = new StringBuffer();
if (attributes != null && attributes.size() > 0) {
for (String key : attributes.keySet()) {
String value = attributes.get(key);
- String encKey = URLEncoder.encode(key, DEFAULT_CHARSET);
- String encValue = URLEncoder.encode(value, DEFAULT_CHARSET);
+ String encKey = URLEncoder.encode(key, DEFAULT_CHARSET);
+ String encValue = URLEncoder.encode(value, DEFAULT_CHARSET);
if (result.length() > 0) {
- result.append(' ');
+ result.append(' ');
}
result.append(encKey);
result.append('=');
@@ -123,7 +124,7 @@
}
return result.toString();
}
-
+
// Converts a single String into a map of attribute keys and values using
URL deencoding
SortedMap<String, String> stringToAttributes(String string) throws
UnsupportedEncodingException {
SortedMap<String, String> attributes = null;
@@ -132,7 +133,7 @@
String[] keyvalues = string.split(" "); // space is the attribute
separator
for (String keyvalue : keyvalues) {
String[] entry = keyvalue.split("=");
- String key = entry[0];
+ String key = entry[0];
String value = entry[1];
attributes.put(key, URLDecoder.decode(value, DEFAULT_CHARSET));
}
@@ -148,17 +149,17 @@
if (attributes.containsKey(TIMESTAMP)) {
throw new TokenProviderException("Invalid token attributes
provided. Parameter '" + TIMESTAMP + "' is a preserved name");
}
-
+
// Add nonce and timestamp attributes
String nonce = DigestUtils.md5Hex(new
Long(System.nanoTime()).toString());
attributes.put(NONCE, nonce);
String timestamp = new Long(System.currentTimeMillis()).toString();
attributes.put(TIMESTAMP, timestamp);
-
+
// First create the unencrypted token
String signature = generateSignature(attributes);
String token = signature + " " + attributesToString(attributes);
-
+
// Encode the token using utf-8
byte[] utf8 = token.getBytes(DEFAULT_CHARSET);
@@ -166,13 +167,11 @@
byte[] enc = m_encryptCipher.doFinal(utf8);
// Encode to base64
- String encryptedToken = Base64.encodeBase64String(enc);
- encryptedToken = encryptedToken.replace("\r", ""); // remove new
lines
- encryptedToken = encryptedToken.replace("\n", ""); // remove new
lines
-
+ String encryptedToken =
StringUtils.newStringUtf8(Base64.encodeBase64(enc, false));
+
// Store the encrypted token
m_tokenStore.addToken(encryptedToken);
-
+
return encryptedToken;
}
catch (BadPaddingException e) {
@@ -193,7 +192,7 @@
if (!m_tokenStore.hasToken(encryptedToken)) {
throw new InvalidTokenException("Token is invalid, token
unknown");
}
-
+
// Decode base64 to get bytes
byte[] dec = Base64.decodeBase64(encryptedToken);
@@ -202,7 +201,7 @@
// Decode using utf-8
String token = new String(utf8, DEFAULT_CHARSET);
-
+
// Now this token consists of signature + token attributes
String signature;
SortedMap<String, String> attributes = null;
@@ -212,7 +211,7 @@
} else {
signature = token;
}
-
+
// Now verify if this signature is valid
if (!verifySignature(attributes, signature)) {
throw new InvalidTokenException("Token is invalid, signature
mismatch");
@@ -231,12 +230,12 @@
m_logService.log(LogService.LOG_ERROR, "Could not decrypt string",
e);
throw new TokenProviderException(e);
}
- }
-
+ }
+
public String updateToken(String encryptedToken, SortedMap<String, String>
newAttributes) throws TokenProviderException, InvalidTokenException {
// First validate that the token is valid and retrieve the original
token attributes
SortedMap<String, String> attributes = verifyToken(encryptedToken);
-
+
// Now update the token attributes with the new ones
if (newAttributes != null && newAttributes.size() > 0) {
for (String key : newAttributes.keySet()) {
@@ -244,15 +243,15 @@
attributes.put(key, value);
}
}
-
+
// Generate a new token
return generateToken(attributes);
}
-
+
public void invalidateToken(String encryptedToken) {
m_tokenStore.removeToken(encryptedToken);
}
-
+
public String getTokenFromRequest(HttpServletRequest request) {
// Use case 1: The token is send along in a cookie with the request.
The cookie is send
// automatically when a request is send directly from the end users
browser to the Amdatu server.
@@ -263,9 +262,9 @@
}
}
}
-
+
// Use case 2: When requests are not send from a browser (for example
calls to gadgets.ui.makeRequest
- // proxied via an openSocial container) the token can be send in the
Authorization header (like Basic
+ // proxied via an openSocial container) the token can be send in the
Authorization header (like Basic
// and Digest HTTP authentication).
String authHeader = request.getHeader("Authorization");
if (authHeader != null && !authHeader.isEmpty()) {