Skip to content
Permalink
Browse files
[CXF-5557] Support for Hawk
git-svn-id: https://svn.apache.org/repos/asf/cxf/trunk@1567600 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
Sergey Beryozkin committed Feb 12, 2014
1 parent b20f995 commit c68ae4f10040ad6057a4f0e278b14651bf139e5a
Show file tree
Hide file tree
Showing 15 changed files with 101 additions and 101 deletions.
@@ -37,7 +37,7 @@
import org.apache.cxf.rs.security.oauth2.common.OAuthError;
import org.apache.cxf.rs.security.oauth2.provider.OAuthJSONProvider;
import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
import org.apache.cxf.rs.security.oauth2.tokens.mac.MacAuthorizationScheme;
import org.apache.cxf.rs.security.oauth2.tokens.hawk.HawkAuthorizationScheme;
import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;

/**
@@ -359,13 +359,13 @@ private static void appendTokenData(StringBuilder sb,
sb.append(OAuthConstants.BEARER_AUTHORIZATION_SCHEME);
sb.append(" ");
sb.append(token.getTokenKey());
} else if (OAuthConstants.MAC_TOKEN_TYPE.equals(token.getTokenType())) {
} else if (OAuthConstants.HAWK_TOKEN_TYPE.equals(token.getTokenType())) {
if (httpProps == null) {
throw new IllegalArgumentException("MAC scheme requires HTTP Request properties");
}
MacAuthorizationScheme macAuthData = new MacAuthorizationScheme(httpProps, token);
String macAlgo = token.getParameters().get(OAuthConstants.MAC_TOKEN_ALGORITHM);
String macKey = token.getParameters().get(OAuthConstants.MAC_TOKEN_KEY);
HawkAuthorizationScheme macAuthData = new HawkAuthorizationScheme(httpProps, token);
String macAlgo = token.getParameters().get(OAuthConstants.HAWK_TOKEN_ALGORITHM);
String macKey = token.getParameters().get(OAuthConstants.HAWK_TOKEN_KEY);
sb.append(macAuthData.toAuthorizationHeader(macAlgo, macKey));
} else {
throw new ProcessingException(new OAuthServiceException("Unsupported token type"));
@@ -16,30 +16,35 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.rs.security.oauth2.tokens.mac;
package org.apache.cxf.rs.security.oauth2.tokens.hawk;

import org.apache.cxf.rs.security.oauth2.common.Client;
import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
import org.apache.cxf.rs.security.oauth2.utils.HmacAlgorithm;
import org.apache.cxf.rs.security.oauth2.utils.HmacUtils;
import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils;

//See http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01
public class MacAccessToken extends ServerAccessToken {
//https://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05
//->
//https://github.com/hueniverse/hawk/blob/master/README.md

public class HawkAccessToken extends ServerAccessToken {

private static final long serialVersionUID = -4331703769692080818L;

public MacAccessToken(Client client,
public HawkAccessToken(Client client,
long lifetime) {
this(client, HmacAlgorithm.HmacSHA256, lifetime);
}

public MacAccessToken(Client client,
public HawkAccessToken(Client client,
String macAuthAlgo,
long lifetime) {
this(client, HmacAlgorithm.toHmacAlgorithm(macAuthAlgo), lifetime);
}

public MacAccessToken(Client client,
public HawkAccessToken(Client client,
HmacAlgorithm macAlgo,
long lifetime) {
this(client,
@@ -48,34 +53,34 @@ public MacAccessToken(Client client,
lifetime,
OAuthUtils.getIssuedAt());
}
public MacAccessToken(Client client,
public HawkAccessToken(Client client,
HmacAlgorithm algo,
String tokenKey,
long lifetime,
long issuedAt) {
super(client, OAuthConstants.MAC_TOKEN_TYPE, tokenKey, lifetime, issuedAt);
super(client, OAuthConstants.HAWK_TOKEN_TYPE, tokenKey, lifetime, issuedAt);
this.setExtraParameters(algo, null);
}

public MacAccessToken(Client client,
public HawkAccessToken(Client client,
HmacAlgorithm algo,
String tokenKey,
String macKey,
long lifetime,
long issuedAt) {
super(client, OAuthConstants.MAC_TOKEN_TYPE, tokenKey, lifetime, issuedAt);
super(client, OAuthConstants.HAWK_TOKEN_TYPE, tokenKey, lifetime, issuedAt);
this.setExtraParameters(algo, macKey);
}

public MacAccessToken(ServerAccessToken token, String newKey) {
super(validateTokenType(token, OAuthConstants.MAC_TOKEN_TYPE), newKey);
public HawkAccessToken(ServerAccessToken token, String newKey) {
super(validateTokenType(token, OAuthConstants.HAWK_TOKEN_TYPE), newKey);
}

private void setExtraParameters(HmacAlgorithm algo, String macKey) {
String theKey = macKey == null ? HmacUtils.generateSecret(algo) : macKey;
super.getParameters().put(OAuthConstants.MAC_TOKEN_KEY,
super.getParameters().put(OAuthConstants.HAWK_TOKEN_KEY,
theKey);
super.getParameters().put(OAuthConstants.MAC_TOKEN_ALGORITHM,
super.getParameters().put(OAuthConstants.HAWK_TOKEN_ALGORITHM,
algo.getOAuthName());
}

@@ -84,10 +89,10 @@ public String getMacId() {
}

public String getMacKey() {
return super.getParameters().get(OAuthConstants.MAC_TOKEN_KEY);
return super.getParameters().get(OAuthConstants.HAWK_TOKEN_KEY);
}

public String getMacAlgorithm() {
return super.getParameters().get(OAuthConstants.MAC_TOKEN_ALGORITHM);
return super.getParameters().get(OAuthConstants.HAWK_TOKEN_ALGORITHM);
}
}
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.rs.security.oauth2.tokens.mac;
package org.apache.cxf.rs.security.oauth2.tokens.hawk;

import java.util.Arrays;
import java.util.Collections;
@@ -34,14 +34,16 @@
import org.apache.cxf.rs.security.oauth2.provider.OAuthDataProvider;
import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
import org.apache.cxf.rs.security.oauth2.utils.AuthorizationUtils;
import org.apache.cxf.rs.security.oauth2.utils.HmacAlgorithm;
import org.apache.cxf.rs.security.oauth2.utils.HmacUtils;
import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;

public class MacAccessTokenValidator implements AccessTokenValidator {
public class HawkAccessTokenValidator implements AccessTokenValidator {
private OAuthDataProvider dataProvider;
private NonceVerifier nonceVerifier;

public List<String> getSupportedAuthorizationSchemes() {
return Collections.singletonList(OAuthConstants.MAC_AUTHORIZATION_SCHEME);
return Collections.singletonList(OAuthConstants.HAWK_AUTHORIZATION_SCHEME);
}

public AccessTokenValidation validateAccessToken(MessageContext mc,
@@ -50,10 +52,10 @@ public AccessTokenValidation validateAccessToken(MessageContext mc,
HttpRequestProperties httpProps = new HttpRequestProperties(mc.getUriInfo().getRequestUri(),
mc.getHttpServletRequest().getMethod());
Map<String, String> schemeParams = getSchemeParameters(authSchemeData);
MacAuthorizationScheme macAuthInfo = new MacAuthorizationScheme(httpProps, schemeParams);
HawkAuthorizationScheme macAuthInfo = new HawkAuthorizationScheme(httpProps, schemeParams);

MacAccessToken macAccessToken = validateSchemeData(macAuthInfo,
schemeParams.get(OAuthConstants.MAC_TOKEN_SIGNATURE));
HawkAccessToken macAccessToken = validateSchemeData(macAuthInfo,
schemeParams.get(OAuthConstants.HAWK_TOKEN_SIGNATURE));
validateTimestampNonce(macAccessToken, macAuthInfo.getTimestamp(), macAuthInfo.getNonce());
return new AccessTokenValidation(macAccessToken);
}
@@ -68,22 +70,21 @@ private static Map<String, String> getSchemeParameters(String authData) {
return attributeMap;
}

protected void validateTimestampNonce(MacAccessToken token, String ts, String nonce) {
// (http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01#section-4.1)
protected void validateTimestampNonce(HawkAccessToken token, String ts, String nonce) {
if (nonceVerifier != null) {
nonceVerifier.verifyNonce(token.getTokenKey(), nonce, ts);
}
}

private MacAccessToken validateSchemeData(MacAuthorizationScheme macAuthInfo,
private HawkAccessToken validateSchemeData(HawkAuthorizationScheme macAuthInfo,
String clientMacString) {
String macKey = macAuthInfo.getMacKey();

ServerAccessToken accessToken = dataProvider.getAccessToken(macKey);
if (!(accessToken instanceof MacAccessToken)) {
if (!(accessToken instanceof HawkAccessToken)) {
throw new OAuthServiceException(OAuthConstants.SERVER_ERROR);
}
MacAccessToken macAccessToken = (MacAccessToken)accessToken;
HawkAccessToken macAccessToken = (HawkAccessToken)accessToken;

String normalizedString = macAuthInfo.getNormalizedRequestString();
try {
@@ -95,7 +96,7 @@ private MacAccessToken validateSchemeData(MacAuthorizationScheme macAuthInfo,
boolean validMac = Arrays.equals(serverMacData, clientMacData);
if (!validMac) {
AuthorizationUtils.throwAuthorizationFailure(Collections
.singleton(OAuthConstants.MAC_AUTHORIZATION_SCHEME));
.singleton(OAuthConstants.HAWK_AUTHORIZATION_SCHEME));
}
} catch (Base64Exception e) {
throw new OAuthServiceException(OAuthConstants.SERVER_ERROR, e);
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.rs.security.oauth2.tokens.mac;
package org.apache.cxf.rs.security.oauth2.tokens.hawk;

import java.security.SecureRandom;
import java.util.Map;
@@ -25,30 +25,33 @@
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.rs.security.oauth2.client.HttpRequestProperties;
import org.apache.cxf.rs.security.oauth2.common.AccessToken;
import org.apache.cxf.rs.security.oauth2.utils.HmacUtils;
import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;

public class MacAuthorizationScheme {
// https://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05
// ->
// https://github.com/hueniverse/hawk/blob/master/README.md
public class HawkAuthorizationScheme {
private static final String SEPARATOR = "\n";

private HttpRequestProperties props;
private String macKey;
private String timestamp;
private String nonce;

public MacAuthorizationScheme(HttpRequestProperties props,
public HawkAuthorizationScheme(HttpRequestProperties props,
AccessToken token) {
this.props = props;
this.macKey = token.getTokenKey();
this.timestamp = Long.toString(System.currentTimeMillis());
this.nonce = generateNonce();
}

public MacAuthorizationScheme(HttpRequestProperties props,
public HawkAuthorizationScheme(HttpRequestProperties props,
Map<String, String> schemeParams) {
this.props = props;
this.macKey = schemeParams.get(OAuthConstants.MAC_TOKEN_ID);
this.timestamp = schemeParams.get(OAuthConstants.MAC_TOKEN_TIMESTAMP);
this.nonce = schemeParams.get(OAuthConstants.MAC_TOKEN_NONCE);
this.macKey = schemeParams.get(OAuthConstants.HAWK_TOKEN_ID);
this.timestamp = schemeParams.get(OAuthConstants.HAWK_TOKEN_TIMESTAMP);
this.nonce = schemeParams.get(OAuthConstants.HAWK_TOKEN_NONCE);
}

public String getMacKey() {
@@ -69,12 +72,11 @@ public String toAuthorizationHeader(String macAlgo, String macSecret) {
String signature = HmacUtils.computeSignature(macAlgo, macSecret, data);

StringBuilder sb = new StringBuilder();
sb.append(OAuthConstants.MAC_AUTHORIZATION_SCHEME).append(" ");
addParameter(sb, OAuthConstants.MAC_TOKEN_ID, macKey, false);
addParameter(sb, OAuthConstants.MAC_TOKEN_NONCE, nonce, false);
addParameter(sb, OAuthConstants.MAC_TOKEN_SIGNATURE, signature, false);
addParameter(sb, OAuthConstants.MAC_TOKEN_TIMESTAMP, timestamp, true);

sb.append(OAuthConstants.HAWK_AUTHORIZATION_SCHEME).append(" ");
addParameter(sb, OAuthConstants.HAWK_TOKEN_ID, macKey, false);
addParameter(sb, OAuthConstants.HAWK_TOKEN_TIMESTAMP, timestamp, false);
addParameter(sb, OAuthConstants.HAWK_TOKEN_NONCE, nonce, false);
addParameter(sb, OAuthConstants.HAWK_TOKEN_SIGNATURE, signature, true);

return sb.toString();
}
@@ -100,6 +102,7 @@ public String getNormalizedRequestString() {
+ requestURI + SEPARATOR
+ props.getHostName() + SEPARATOR
+ props.getPort() + SEPARATOR
+ "" + SEPARATOR
+ "" + SEPARATOR;

return value;
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.rs.security.oauth2.tokens.mac;
package org.apache.cxf.rs.security.oauth2.tokens.hawk;

import java.io.Serializable;

@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.rs.security.oauth2.tokens.mac;
package org.apache.cxf.rs.security.oauth2.tokens.hawk;

import java.io.Serializable;
import java.util.ArrayList;
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.rs.security.oauth2.tokens.mac;
package org.apache.cxf.rs.security.oauth2.tokens.hawk;

public interface NonceStore {

@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.rs.security.oauth2.tokens.mac;
package org.apache.cxf.rs.security.oauth2.tokens.hawk;

import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;

@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.rs.security.oauth2.tokens.mac;
package org.apache.cxf.rs.security.oauth2.tokens.hawk;

import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
@@ -17,13 +17,12 @@
* under the License.
*/

package org.apache.cxf.rs.security.oauth2.tokens.mac;
package org.apache.cxf.rs.security.oauth2.utils;

import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;

public enum HmacAlgorithm {
HmacSHA1(OAuthConstants.MAC_TOKEN_ALGO_HMAC_SHA_1),
HmacSHA256(OAuthConstants.MAC_TOKEN_ALGO_HMAC_SHA_256);
HmacSHA1(HmacUtils.ALGO_HMAC_SHA_1),
HmacSHA256(HmacUtils.ALGO_HMAC_SHA_256);

private final String oauthName;

@@ -40,10 +39,10 @@ public String getJavaName() {
}

public static HmacAlgorithm toHmacAlgorithm(String value) {
if (OAuthConstants.MAC_TOKEN_ALGO_HMAC_SHA_1.equals(value)) {
if (HmacUtils.ALGO_HMAC_SHA_1.equals(value)) {
return HmacSHA1;
}
if (OAuthConstants.MAC_TOKEN_ALGO_HMAC_SHA_256.equals(value)) {
if (HmacUtils.ALGO_HMAC_SHA_256.equals(value)) {
return HmacSHA256;
}
return null;
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.rs.security.oauth2.tokens.mac;
package org.apache.cxf.rs.security.oauth2.utils;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
@@ -28,18 +28,18 @@

import org.apache.cxf.common.util.Base64Utility;
import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;

public final class HmacUtils {
public static final String ALGO_HMAC_SHA_1 = "hmac-sha-1";
public static final String ALGO_HMAC_SHA_256 = "hmac-sha-256";

private HmacUtils() {

}

public static String computeSignature(String macAlgoOAuthName, String macSecret, String data) {
HmacAlgorithm theAlgo = HmacAlgorithm.toHmacAlgorithm(macAlgoOAuthName);
return HmacUtils.computeHmacString(macSecret,
theAlgo.getJavaName(),
data);
return computeHmacString(macSecret, theAlgo.getJavaName(), data);
}

/**

0 comments on commit c68ae4f

Please sign in to comment.