Author: sergeyb
Date: Fri Jan 25 12:42:02 2013
New Revision: 1438472
URL: http://svn.apache.org/viewvc?rev=1438472&view=rev
Log:
[CXF-4783] NonceVerifier implementation, patch from Sasi M applied with very
minor updates
Added:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceHistory.java
(with props)
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceStore.java
(with props)
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifierImpl.java
(with props)
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/NonceVerifierImplTest.java
(with props)
Added:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceHistory.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceHistory.java?rev=1438472&view=auto
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceHistory.java
(added)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceHistory.java
Fri Jan 25 12:42:02 2013
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.oauth2.tokens.mac;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class NonceHistory implements Serializable {
+
+ private static final long serialVersionUID = -6404833046910698956L;
+
+ private final long requestTimeDelta;
+ private final List<Nonce> nonceList = new ArrayList<Nonce>();
+
+ public NonceHistory(long requestTimeDelta, Nonce nonce) {
+ this.requestTimeDelta = requestTimeDelta;
+ nonceList.add(nonce);
+ }
+
+ public void addNonce(Nonce nonce) {
+ nonceList.add(nonce);
+ }
+
+ public long getRequestTimeDelta() {
+ return requestTimeDelta;
+ }
+
+ public List<Nonce> getNonceList() {
+ return nonceList;
+ }
+
+ public Collection<Nonce> findMatchingNonces(String nonceString, long ts) {
+ List<Nonce> nonceMatches = new ArrayList<Nonce>();
+ for (Nonce nonce : getNonceList()) {
+ if (nonce.getNonceString().equals(nonceString) && nonce.getTs() ==
ts) {
+ nonceMatches.add(nonce);
+ }
+ }
+ return nonceMatches;
+ }
+
+}
\ No newline at end of file
Propchange:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceHistory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceHistory.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceStore.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceStore.java?rev=1438472&view=auto
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceStore.java
(added)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceStore.java
Fri Jan 25 12:42:02 2013
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.oauth2.tokens.mac;
+
+public interface NonceStore {
+
+ void storeNonce(String tokenKey, Nonce nonce, long requestTimeDelta);
+
+ NonceHistory getNonceHistory(String tokenKey);
+}
\ No newline at end of file
Propchange:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceStore.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceStore.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifierImpl.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifierImpl.java?rev=1438472&view=auto
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifierImpl.java
(added)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifierImpl.java
Fri Jan 25 12:42:02 2013
@@ -0,0 +1,75 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.oauth2.tokens.mac;
+
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+
+public class NonceVerifierImpl implements NonceVerifier {
+ private NonceStore nonceStore;
+ private long allowedWindow; // 2000 ms
+
+ public void verifyNonce(String tokenKey, String clientNonceString, String
clientTimestampString)
+ throws OAuthServiceException {
+
+ if (StringUtils.isEmpty(clientNonceString)
+ || StringUtils.isEmpty(clientTimestampString)) {
+ throw new OAuthServiceException("Nonce or timestamp is not
available");
+ }
+
+ long serverClock = System.currentTimeMillis();
+ NonceHistory nonceHistory = nonceStore.getNonceHistory(tokenKey);
+ boolean firstTimeRequest = false;
+ if (nonceHistory == null) {
+ firstTimeRequest = true;
+ }
+ long clientTimestamp = Long.valueOf(clientTimestampString);
+ if (firstTimeRequest) {
+ long requestTimeDelta = serverClock - clientTimestamp;
+ Nonce nonce = new Nonce(clientNonceString, clientTimestamp);
+ nonceStore.storeNonce(tokenKey, nonce, requestTimeDelta);
+ } else {
+ checkAdjustedRequestTime(serverClock, clientTimestamp,
nonceHistory);
+ checkNonceHistory(nonceHistory, clientNonceString,
clientTimestamp);
+ }
+ }
+
+ private static void checkNonceHistory(NonceHistory nonceHistory, final
String clientNonceString,
+ final long ts) throws
OAuthServiceException {
+ if (!nonceHistory.findMatchingNonces(clientNonceString, ts).isEmpty())
{
+ throw new OAuthServiceException("Duplicate nonce");
+ }
+ }
+
+ private void checkAdjustedRequestTime(long serverClock, long
clientTimestamp, NonceHistory nonceHistory) {
+ long adjustedRequestTime = clientTimestamp +
nonceHistory.getRequestTimeDelta();
+ long requestDelta = Math.abs(serverClock - adjustedRequestTime);
+ if (requestDelta > allowedWindow) {
+ throw new OAuthServiceException("Timestamp is invalid");
+ }
+ }
+
+ public void setAllowedWindow(long allowedWindow) {
+ this.allowedWindow = allowedWindow;
+ }
+
+ public void setNonceStore(NonceStore nonceStore) {
+ this.nonceStore = nonceStore;
+ }
+}
\ No newline at end of file
Propchange:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifierImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/tokens/mac/NonceVerifierImpl.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/NonceVerifierImplTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/NonceVerifierImplTest.java?rev=1438472&view=auto
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/NonceVerifierImplTest.java
(added)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/NonceVerifierImplTest.java
Fri Jan 25 12:42:02 2013
@@ -0,0 +1,96 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.oauth2.token.mac;
+
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+import org.apache.cxf.rs.security.oauth2.tokens.mac.Nonce;
+import org.apache.cxf.rs.security.oauth2.tokens.mac.NonceHistory;
+import org.apache.cxf.rs.security.oauth2.tokens.mac.NonceStore;
+import org.apache.cxf.rs.security.oauth2.tokens.mac.NonceVerifierImpl;
+import org.easymock.EasyMock;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class NonceVerifierImplTest extends Assert {
+
+ private NonceVerifierImpl nonceVerifier;
+ private NonceStore nonceStore = EasyMock.createMock(NonceStore.class);
+
+ @Before
+ public void setUp() {
+ nonceVerifier = new NonceVerifierImpl();
+ nonceVerifier.setNonceStore(nonceStore);
+ }
+
+ @Test
+ public void testVerifyNonce() {
+ long now = System.currentTimeMillis();
+ Nonce nonce1 = new Nonce("nonce1", now - 2000); // first request 2
seconds back
+ Nonce nonce2 = new Nonce("nonce2", now - 1000); // second request 1
second back
+ NonceHistory nonceHistory = new NonceHistory(200, nonce1); // first
request time delta is 200ms
+ nonceHistory.addNonce(nonce2);
+
+
EasyMock.expect(nonceStore.getNonceHistory("testTokenKey")).andReturn(nonceHistory);
+ EasyMock.replay(nonceStore);
+ nonceVerifier.setAllowedWindow(2000); // allowed window is 2 seconds
+ nonceVerifier.verifyNonce("testTokenKey", "nonce3", Long.toString(now
- 500));
+ EasyMock.verify(nonceStore);
+ }
+
+ @Test
+ public void testVerifyNonceDuplicateNonce() {
+ long now = System.currentTimeMillis();
+ Nonce nonce1 = new Nonce("nonce1", now - 2000); // first request 2
seconds back
+ Nonce nonce2 = new Nonce("nonce2", now - 1000); // second request 1
second back
+ NonceHistory nonceHistory = new NonceHistory(200, nonce1); // first
request time delta is 200ms
+ nonceHistory.addNonce(nonce2);
+
+
EasyMock.expect(nonceStore.getNonceHistory("testTokenKey")).andReturn(nonceHistory);
+ EasyMock.replay(nonceStore);
+ nonceVerifier.setAllowedWindow(2000); // allowed window is 2 seconds
+ try {
+ nonceVerifier.verifyNonce("testTokenKey", "nonce2",
Long.toString(now - 1000));
+ fail("Exception expected");
+ } catch (OAuthServiceException ex) {
+ assertEquals("Duplicate nonce", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testVerifyNonceInvalidTimestamp() {
+ long now = System.currentTimeMillis();
+ Nonce nonce1 = new Nonce("nonce1", now - 2000); // first request 2
seconds back
+ Nonce nonce2 = new Nonce("nonce2", now - 1000); // second request 1
second back
+ NonceHistory nonceHistory = new NonceHistory(200, nonce1); // first
request time delta is 200ms
+ nonceHistory.addNonce(nonce2);
+
+
EasyMock.expect(nonceStore.getNonceHistory("testTokenKey")).andReturn(nonceHistory);
+ EasyMock.replay(nonceStore);
+ nonceVerifier.setAllowedWindow(2000); // allowed window is 2 seconds
+ try {
+ nonceVerifier.verifyNonce("testTokenKey", "nonce3",
Long.toString(now - 5000)); // very old timestamp
+ fail("Exception expected");
+ } catch (OAuthServiceException ex) {
+ assertEquals("Timestamp is invalid", ex.getMessage());
+ }
+ }
+
+}
\ No newline at end of file
Propchange:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/NonceVerifierImplTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/token/mac/NonceVerifierImplTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date