Author: sergeyb
Date: Mon Feb 27 17:50:21 2012
New Revision: 1294248
URL: http://svn.apache.org/viewvc?rev=1294248&view=rev
Log:
[CXF-4112] Various updates to make the initial code flow starting to work, a
lot of refactoring to follow
Added:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/provider/OAuthJSONProvider.java
(with props)
Modified:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/client/OAuthClientUtils.java
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/AccessToken.java
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/AccessTokenType.java
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/ClientAccessToken.java
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/OAuthAuthorizationData.java
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/OAuthError.java
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/grants/code/AuthorizationCodeGrantHandler.java
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/provider/OAuthServiceException.java
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AbstractOAuthService.java
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AccessTokenService.java
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AuthorizationCodeGrantService.java
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/utils/OAuthConstants.java
Modified:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/client/OAuthClientUtils.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/client/OAuthClientUtils.java?rev=1294248&r1=1294247&r2=1294248&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/client/OAuthClientUtils.java
(original)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/client/OAuthClientUtils.java
Mon Feb 27 17:50:21 2012
@@ -18,8 +18,13 @@
*/
package org.apache.cxf.rs.security.oauth.client;
+import java.io.IOException;
+import java.io.InputStream;
import java.net.URI;
+import java.util.Collections;
+import java.util.Map;
+import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import org.apache.cxf.common.util.Base64Utility;
@@ -29,7 +34,10 @@ import org.apache.cxf.jaxrs.ext.form.For
import org.apache.cxf.rs.security.oauth.common.AccessTokenGrant;
import org.apache.cxf.rs.security.oauth.common.AccessTokenType;
import org.apache.cxf.rs.security.oauth.common.ClientAccessToken;
+import org.apache.cxf.rs.security.oauth.common.OAuthError;
+import org.apache.cxf.rs.security.oauth.provider.OAuthJSONProvider;
import org.apache.cxf.rs.security.oauth.provider.OAuthServiceException;
+import org.apache.cxf.rs.security.oauth.utils.OAuthConstants;
/**
* The utility class for simplifying making OAuth request and access token
@@ -56,10 +64,10 @@ public final class OAuthClientUtils {
clientId,
scope);
if (redirectUri != null) {
- ub.queryParam("redirect_uri", redirectUri);
+ ub.queryParam(OAuthConstants.REDIRECT_URI, redirectUri);
}
if (state != null) {
- ub.queryParam("state", state);
+ ub.queryParam(OAuthConstants.STATE, state);
}
return ub.build();
}
@@ -69,11 +77,12 @@ public final class OAuthClientUtils {
String scope) {
UriBuilder ub = UriBuilder.fromUri(authorizationServiceURI);
if (clientId != null) {
- ub.queryParam("client_id", clientId);
+ ub.queryParam(OAuthConstants.CLIENT_ID, clientId);
}
if (scope != null) {
- ub.queryParam("scope", scope);
+ ub.queryParam(OAuthConstants.SCOPE, scope);
}
+ ub.queryParam(OAuthConstants.RESPONSE_TYPE,
OAuthConstants.CODE_RESPONSE_TYPE);
return ub;
}
@@ -84,25 +93,65 @@ public final class OAuthClientUtils {
return getAccessToken(accessTokenService, consumer, grant, true);
}
+ public static ClientAccessToken getAccessToken(String
accessTokenServiceUri,
+ Consumer consumer,
+ AccessTokenGrant grant,
+ boolean
setAuthorizationHeader)
+ throws OAuthServiceException {
+ OAuthJSONProvider provider = new OAuthJSONProvider();
+ WebClient accessTokenService =
+ WebClient.create(accessTokenServiceUri,
Collections.singletonList(provider));
+ accessTokenService.accept("application/json");
+ return getAccessToken(accessTokenService, consumer, grant, true);
+ }
+
public static ClientAccessToken getAccessToken(WebClient
accessTokenService,
Consumer consumer,
AccessTokenGrant grant,
boolean
setAuthorizationHeader)
throws OAuthServiceException {
- StringBuilder sb = new StringBuilder();
- sb.append("Basic ");
+ Form form = new Form(grant.toMap());
+
+ if (setAuthorizationHeader) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Basic ");
+ try {
+ String data = consumer.getKey() + ":" + consumer.getSecret();
+ sb.append(Base64Utility.encode(data.getBytes("UTF-8")));
+ } catch (Exception ex) {
+ throw new ClientWebApplicationException(ex);
+ }
+ accessTokenService.header("Authorization", sb.toString());
+ } else {
+ form.set(OAuthConstants.CLIENT_ID, consumer.getKey());
+ form.set(OAuthConstants.CLIENT_SECRET, consumer.getSecret());
+ }
+ Response response = accessTokenService.form(form);
+ Map<String, String> map = null;
try {
- String data = consumer.getKey() + ":" + consumer.getSecret();
- sb.append(Base64Utility.encode(data.getBytes("UTF-8")));
- } catch (Exception ex) {
+ map = new
OAuthJSONProvider().readJSONResponse((InputStream)response.getEntity());
+ } catch (IOException ex) {
throw new ClientWebApplicationException(ex);
}
- accessTokenService.header("Authorization", sb.toString());
-
- Form form = new Form(grant.toMap());
- accessTokenService.accept("application/json");
- return accessTokenService.post(form, ClientAccessToken.class);
+ if (200 == response.getStatus()) {
+ if (map.containsKey(OAuthConstants.ACCESS_TOKEN)
+ && map.containsKey(OAuthConstants.ACCESS_TOKEN_TYPE)) {
+ String type = map.get(OAuthConstants.ACCESS_TOKEN_TYPE);
+
+ ClientAccessToken token = new ClientAccessToken(
+ AccessTokenType.fromString(type),
+
map.get(OAuthConstants.ACCESS_TOKEN));
+ return token;
+ } else {
+ throw new OAuthServiceException(OAuthConstants.SERVER_ERROR);
+ }
+ } else if (400 == response.getStatus() &&
map.containsValue(OAuthConstants.ERROR_KEY)) {
+ OAuthError error = new
OAuthError(map.get(OAuthConstants.ERROR_KEY),
+
map.get(OAuthConstants.ERROR_DESCRIPTION_KEY));
+ throw new OAuthServiceException(error);
+ }
+ throw new OAuthServiceException(OAuthConstants.SERVER_ERROR);
}
/**
Modified:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/AccessToken.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/AccessToken.java?rev=1294248&r1=1294247&r2=1294248&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/AccessToken.java
(original)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/AccessToken.java
Mon Feb 27 17:50:21 2012
@@ -20,16 +20,12 @@ package org.apache.cxf.rs.security.oauth
import java.util.Map;
-import javax.xml.bind.annotation.XmlElement;
-
/**
* Base Token representation
*/
public abstract class AccessToken {
- @XmlElement(name = "access_token")
private String tokenKey;
- @XmlElement(name = "token_type")
private AccessTokenType tokenType;
private Map<String, String> parameters;
Modified:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/AccessTokenType.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/AccessTokenType.java?rev=1294248&r1=1294247&r2=1294248&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/AccessTokenType.java
(original)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/AccessTokenType.java
Mon Feb 27 17:50:21 2012
@@ -28,6 +28,14 @@ public enum AccessTokenType {
this.type = type;
}
+ public static AccessTokenType fromString(String str) {
+ if ("bearer".equals(str)) {
+ return BEARER;
+ } else {
+ throw new IllegalArgumentException(str);
+ }
+ }
+
public String getTokenType() {
return type;
}
@@ -35,4 +43,5 @@ public enum AccessTokenType {
public String toString() {
return type;
}
+
}
Modified:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/ClientAccessToken.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/ClientAccessToken.java?rev=1294248&r1=1294247&r2=1294248&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/ClientAccessToken.java
(original)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/ClientAccessToken.java
Mon Feb 27 17:50:21 2012
@@ -18,39 +18,38 @@
*/
package org.apache.cxf.rs.security.oauth.common;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
/**
* Base Token representation
*/
-@XmlRootElement
public class ClientAccessToken extends AccessToken {
- @XmlElement(name = "scope")
- private String approvedScope;
- @XmlElement(name = "refresh_token")
- private String refreshToken;
-
+ private String scope;
+ private String rToken;
+
+ public ClientAccessToken(String type, String tokenKey) {
+ this(AccessTokenType.valueOf(type), tokenKey);
+ }
+
public ClientAccessToken(AccessTokenType type, String tokenKey) {
super(type, tokenKey);
}
public void setApprovedScope(String approvedScope) {
- this.approvedScope = approvedScope;
+ this.scope = approvedScope;
}
public String getApprovedScope() {
- return approvedScope;
+ return scope;
}
public void setRefreshToken(String refreshToken) {
- this.refreshToken = refreshToken;
+ this.rToken = refreshToken;
}
public String getRefreshToken() {
- return refreshToken;
+ return rToken;
}
}
Modified:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/OAuthAuthorizationData.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/OAuthAuthorizationData.java?rev=1294248&r1=1294247&r2=1294248&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/OAuthAuthorizationData.java
(original)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/OAuthAuthorizationData.java
Mon Feb 27 17:50:21 2012
@@ -38,6 +38,7 @@ public class OAuthAuthorizationData impl
private String state;
private String proposedScope;
private String authenticityToken;
+ private String replyTo;
private String applicationName;
private String applicationWebUri;
@@ -128,4 +129,12 @@ public class OAuthAuthorizationData impl
return proposedScope;
}
+ public void setReplyTo(String replyTo) {
+ this.replyTo = replyTo;
+ }
+
+ public String getReplyTo() {
+ return replyTo;
+ }
+
}
Modified:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/OAuthError.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/OAuthError.java?rev=1294248&r1=1294247&r2=1294248&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/OAuthError.java
(original)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/common/OAuthError.java
Mon Feb 27 17:50:21 2012
@@ -18,21 +18,12 @@
*/
package org.apache.cxf.rs.security.oauth.common;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-@XmlRootElement
public class OAuthError {
- public static final String INVALID_REQUEST = "invalid_request";
-
- @XmlElement(name = "error")
private String error;
- @XmlElement(name = "error_description")
private String errorDescription;
- @XmlElement(name = "error_uri")
private String errorUri;
- @XmlElement(name = "state")
private String state;
public OAuthError() {
Modified:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/grants/code/AuthorizationCodeGrantHandler.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/grants/code/AuthorizationCodeGrantHandler.java?rev=1294248&r1=1294247&r2=1294248&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/grants/code/AuthorizationCodeGrantHandler.java
(original)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/grants/code/AuthorizationCodeGrantHandler.java
Mon Feb 27 17:50:21 2012
@@ -31,14 +31,12 @@ import org.apache.cxf.rs.security.oauth.
import org.apache.cxf.rs.security.oauth.provider.OAuthServiceException;
import org.apache.cxf.rs.security.oauth.tokens.bearer.BearerAccessToken;
import org.apache.cxf.rs.security.oauth.utils.MD5SequenceGenerator;
+import org.apache.cxf.rs.security.oauth.utils.OAuthConstants;
import org.apache.cxf.rs.security.oauth.utils.OAuthUtils;
public class AuthorizationCodeGrantHandler implements AccessTokenGrantHandler {
- private static final String GRANT_TYPE = "grant_type";
- private static final String AUTHORIZATION_CODE_GRANT =
"authorization_code";
- private static final String REDIRECT_URI = "redirect_uri";
private static final long DEFAULT_TOKEN_LIFETIME = 3600L;
@@ -46,24 +44,25 @@ public class AuthorizationCodeGrantHandl
private long tokenLifetime = DEFAULT_TOKEN_LIFETIME;
public List<String> getSupportedGrantTypes() {
- return Collections.singletonList(AUTHORIZATION_CODE_GRANT);
+ return
Collections.singletonList(OAuthConstants.AUTHORIZATION_CODE_GRANT);
}
public ServerAccessToken createAccessToken(Client client,
MultivaluedMap<String, String> params)
throws OAuthServiceException {
- ServerAuthorizationCodeGrant grant =
codeProvider.removeCodeGrant(params.getFirst(GRANT_TYPE));
+ ServerAuthorizationCodeGrant grant =
+
codeProvider.removeCodeGrant(params.getFirst(OAuthConstants.AUTHORIZATION_CODE_VALUE));
if (grant == null) {
return null;
}
if (OAuthUtils.isExpired(grant.getIssuedAt(), grant.getLifetime())) {
- throw new OAuthServiceException("invalid_grant");
+ throw new OAuthServiceException(OAuthConstants.INVALID_GRANT);
}
String expectedRedirectUri = grant.getRedirectUri();
if (expectedRedirectUri != null) {
- String providedRedirectUri = params.getFirst(REDIRECT_URI);
+ String providedRedirectUri =
params.getFirst(OAuthConstants.REDIRECT_URI);
if (providedRedirectUri == null ||
!providedRedirectUri.equals(expectedRedirectUri)) {
- throw new OAuthServiceException("invalid_request");
+ throw new
OAuthServiceException(OAuthConstants.INVALID_REQUEST);
}
}
BearerAccessToken token = new BearerAccessToken(client,
@@ -83,7 +82,7 @@ public class AuthorizationCodeGrantHandl
byte[] bytes = UUID.randomUUID().toString().getBytes("UTF-8");
return new MD5SequenceGenerator().generate(bytes);
} catch (Exception ex) {
- throw new OAuthServiceException("server_error", ex);
+ throw new OAuthServiceException(OAuthConstants.SERVER_ERROR, ex);
}
}
public void setTokenLifetime(long tokenLifetime) {
Added:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/provider/OAuthJSONProvider.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/provider/OAuthJSONProvider.java?rev=1294248&view=auto
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/provider/OAuthJSONProvider.java
(added)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/provider/OAuthJSONProvider.java
Mon Feb 27 17:50:21 2012
@@ -0,0 +1,145 @@
+/**
+ * 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.oauth.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxrs.client.ClientWebApplicationException;
+import org.apache.cxf.rs.security.oauth.common.ClientAccessToken;
+import org.apache.cxf.rs.security.oauth.common.OAuthError;
+import org.apache.cxf.rs.security.oauth.utils.OAuthConstants;
+
+@Provider
+@Produces("application/json")
+@Consumes("application/json")
+public class OAuthJSONProvider implements MessageBodyWriter<Object>,
+ MessageBodyReader<Map<String, String>> {
+
+ public long getSize(Object obj, Class<?> clt, Type t, Annotation[] anns,
MediaType mt) {
+ return -1;
+ }
+
+ public boolean isWriteable(Class<?> cls, Type t, Annotation[] anns,
MediaType mt) {
+ return cls == ClientAccessToken.class || cls == OAuthError.class;
+ }
+
+ public void writeTo(Object obj, Class<?> cls, Type t, Annotation[] anns,
MediaType mt,
+ MultivaluedMap<String, Object> headers, OutputStream
os) throws IOException,
+ WebApplicationException {
+ if (obj instanceof ClientAccessToken) {
+ writeAccessToken((ClientAccessToken)obj, os);
+ } else {
+ writeOAuthError((OAuthError)obj, os);
+ }
+ }
+
+ private void writeOAuthError(OAuthError obj, OutputStream os) throws
IOException {
+ StringBuilder sb = new StringBuilder();
+ sb.append("{");
+ appendJsonPair(sb, OAuthConstants.ERROR_KEY, obj.getError());
+ if (obj.getErrorDescription() != null) {
+ sb.append(",");
+ appendJsonPair(sb, OAuthConstants.ERROR_DESCRIPTION_KEY,
obj.getErrorDescription());
+ }
+ // etc
+ sb.append("}");
+ String result = sb.toString();
+ os.write(result.getBytes("UTF-8"));
+ os.flush();
+ }
+
+ private void writeAccessToken(ClientAccessToken obj, OutputStream os)
throws IOException {
+ StringBuilder sb = new StringBuilder();
+ sb.append("{");
+ appendJsonPair(sb, OAuthConstants.ACCESS_TOKEN, obj.getTokenKey());
+ sb.append(",");
+ appendJsonPair(sb, OAuthConstants.ACCESS_TOKEN_TYPE,
obj.getTokenType().toString());
+ // etc
+ sb.append("}");
+ String result = sb.toString();
+ os.write(result.getBytes("UTF-8"));
+ os.flush();
+ }
+
+ private void appendJsonPair(StringBuilder sb, String key, String value) {
+ sb.append("\"").append(key).append("\"");
+ sb.append(":");
+ sb.append("\"").append(value).append("\"");
+ }
+
+ public boolean isReadable(Class<?> cls, Type t, Annotation[] anns,
MediaType mt) {
+ return Map.class.isAssignableFrom(cls);
+ }
+
+ public Map<String, String> readFrom(Class<Map<String, String>> cls, Type
t, Annotation[] anns,
+ MediaType mt, MultivaluedMap<String,
String> headers, InputStream is)
+ throws IOException, WebApplicationException {
+ return readJSONResponse(is);
+ }
+
+ public Map<String, String> readJSONResponse(InputStream is) throws
IOException {
+ String str = IOUtils.readStringFromStream(is).trim();
+ if (str.isEmpty()) {
+ return Collections.emptyMap();
+ }
+ if (!str.startsWith("{") || !str.endsWith("}")) {
+ throw new ClientWebApplicationException("JSON Sequence is broken");
+ }
+ Map<String, String> map = new HashMap<String, String>();
+
+ str = str.substring(1, str.length() - 1).trim();
+ String[] jsonPairs = str.split(",");
+ for (int i = 0; i < jsonPairs.length; i++) {
+ String pair = jsonPairs[i].trim();
+ if (pair.length() == 0) {
+ continue;
+ }
+ String[] entry = pair.split(":");
+ String key = entry[0].trim();
+ if (key.startsWith("\"") && key.endsWith("\"")) {
+ key = key.substring(1, key.length() - 1);
+ }
+ String value = entry[1].trim();
+ if (value.startsWith("\"") && value.endsWith("\"")) {
+ value = value.substring(1, value.length() - 1);
+ }
+ map.put(key, value);
+ }
+
+ return map;
+ }
+
+}
Propchange:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/provider/OAuthJSONProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/provider/OAuthJSONProvider.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/provider/OAuthServiceException.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/provider/OAuthServiceException.java?rev=1294248&r1=1294247&r2=1294248&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/provider/OAuthServiceException.java
(original)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/provider/OAuthServiceException.java
Mon Feb 27 17:50:21 2012
@@ -19,13 +19,16 @@
package org.apache.cxf.rs.security.oauth.provider;
+import org.apache.cxf.rs.security.oauth.common.OAuthError;
+
/**
* Encapsulates OAuth-related problems
*/
public class OAuthServiceException extends RuntimeException {
-
+
private static final long serialVersionUID = 343738539234766320L;
+ private OAuthError error;
public OAuthServiceException(String message) {
super(message);
@@ -35,6 +38,17 @@ public class OAuthServiceException exten
super(message, cause);
}
+ public OAuthServiceException(OAuthError error) {
+ this.error = error;
+ }
+ public OAuthServiceException(OAuthError error, Throwable cause) {
+ super(cause);
+ this.error = error;
+ }
+
+ public OAuthError getError() {
+ return error;
+ }
}
Modified:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AbstractOAuthService.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AbstractOAuthService.java?rev=1294248&r1=1294247&r2=1294248&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AbstractOAuthService.java
(original)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AbstractOAuthService.java
Mon Feb 27 17:50:21 2012
@@ -29,13 +29,12 @@ import org.apache.cxf.rs.security.oauth.
import org.apache.cxf.rs.security.oauth.common.OAuthError;
import org.apache.cxf.rs.security.oauth.provider.OAuthDataProvider;
import org.apache.cxf.rs.security.oauth.provider.OAuthServiceException;
+import org.apache.cxf.rs.security.oauth.utils.OAuthConstants;
/**
* Abstract utility class which OAuth services extend
*/
public abstract class AbstractOAuthService {
- protected static final String CLIENT_ID = "client_id";
-
private MessageContext mc;
private OAuthDataProvider dataProvider;
@@ -61,7 +60,7 @@ public abstract class AbstractOAuthServi
}
protected Client getClient(MultivaluedMap<String, String> params) {
- return getClient(params.getFirst(CLIENT_ID));
+ return getClient(params.getFirst(OAuthConstants.CLIENT_ID));
}
protected Client getClient(String clientId) {
Client client = null;
@@ -81,7 +80,8 @@ public abstract class AbstractOAuthServi
}
protected void reportInvalidRequestError(String errorDescription) {
- OAuthError error = new OAuthError(OAuthError.INVALID_REQUEST,
errorDescription);
+ OAuthError error =
+ new OAuthError(OAuthConstants.INVALID_REQUEST, errorDescription);
throw new WebApplicationException(
Response.status(400).type(MediaType.APPLICATION_JSON).entity(error).build());
}
Modified:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AccessTokenService.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AccessTokenService.java?rev=1294248&r1=1294247&r2=1294248&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AccessTokenService.java
(original)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AccessTokenService.java
Mon Feb 27 17:50:21 2012
@@ -20,6 +20,7 @@
package org.apache.cxf.rs.security.oauth.services;
import java.security.Principal;
+import java.util.Collections;
import java.util.List;
import javax.ws.rs.Consumes;
@@ -35,20 +36,17 @@ import org.apache.cxf.rs.security.oauth.
import org.apache.cxf.rs.security.oauth.common.ClientAccessToken;
import org.apache.cxf.rs.security.oauth.common.OAuthError;
import org.apache.cxf.rs.security.oauth.common.ServerAccessToken;
+import
org.apache.cxf.rs.security.oauth.grants.code.AuthorizationCodeDataProvider;
import
org.apache.cxf.rs.security.oauth.grants.code.AuthorizationCodeGrantHandler;
import org.apache.cxf.rs.security.oauth.provider.AccessTokenGrantHandler;
import org.apache.cxf.rs.security.oauth.provider.OAuthServiceException;
import org.apache.cxf.rs.security.oauth.utils.AuthorizationUtils;
+import org.apache.cxf.rs.security.oauth.utils.OAuthConstants;
@Path("/token")
public class AccessTokenService extends AbstractOAuthService {
- private static final String CLIENT_SECRET = "client_secret";
- private static final String GRANT_TYPE = "grant_type";
- private static final String INVALID_GRANT = "invalid_grant";
- private static final String UNSUPPORTED_GRANT_TYPE =
"unsupported_grant_type";
-
- private List<AccessTokenGrantHandler> grantHandlers;
+ private List<AccessTokenGrantHandler> grantHandlers =
Collections.emptyList();
public void setGrantHandlers(List<AccessTokenGrantHandler> handlers) {
grantHandlers = handlers;
@@ -62,7 +60,7 @@ public class AccessTokenService extends
AccessTokenGrantHandler handler = findGrantHandler(params);
if (handler == null) {
- return createErrorResponse(params, UNSUPPORTED_GRANT_TYPE);
+ return createErrorResponse(params,
OAuthConstants.UNSUPPORTED_GRANT_TYPE);
}
ServerAccessToken serverToken = null;
@@ -72,7 +70,7 @@ public class AccessTokenService extends
// the error response is to be returned next
}
if (serverToken == null) {
- return createErrorResponse(params, INVALID_GRANT);
+ return createErrorResponse(params, OAuthConstants.INVALID_GRANT);
}
getDataProvider().persistAccessToken(serverToken);
@@ -86,10 +84,10 @@ public class AccessTokenService extends
Client client = null;
SecurityContext sc = getMessageContext().getSecurityContext();
- if (params.containsKey(CLIENT_ID)) {
+ if (params.containsKey(OAuthConstants.CLIENT_ID)) {
// both client_id and client_secret are expected in the form
payload
- client = getAndValidateClient(params.getFirst(CLIENT_ID),
- params.getFirst(CLIENT_SECRET));
+ client =
getAndValidateClient(params.getFirst(OAuthConstants.CLIENT_ID),
+
params.getFirst(OAuthConstants.CLIENT_SECRET));
} else if (sc.getUserPrincipal() != null) {
// client has already authenticated
Principal p = sc.getUserPrincipal();
@@ -103,7 +101,7 @@ public class AccessTokenService extends
// in which case the mapping between the scheme and the
client_id
// should've been done, in which case the client_id is expected
// on the current message
- Object clientIdProp = getMessageContext().get(CLIENT_ID);
+ Object clientIdProp =
getMessageContext().get(OAuthConstants.CLIENT_ID);
if (clientIdProp != null) {
client = getClient(clientIdProp.toString());
}
@@ -133,7 +131,7 @@ public class AccessTokenService extends
}
protected AccessTokenGrantHandler findGrantHandler(MultivaluedMap<String,
String> params) {
- String grantType = params.getFirst(GRANT_TYPE);
+ String grantType = params.getFirst(OAuthConstants.GRANT_TYPE);
if (grantType != null) {
for (AccessTokenGrantHandler handler : grantHandlers) {
if (handler.getSupportedGrantTypes().contains(grantType)) {
@@ -143,6 +141,8 @@ public class AccessTokenService extends
if (grantHandlers.size() == 0) {
AuthorizationCodeGrantHandler handler = new
AuthorizationCodeGrantHandler();
if (handler.getSupportedGrantTypes().contains(grantType)) {
+ handler.setCodeProvider(
+
(AuthorizationCodeDataProvider)super.getDataProvider());
return handler;
}
}
Modified:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AuthorizationCodeGrantService.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AuthorizationCodeGrantService.java?rev=1294248&r1=1294247&r2=1294248&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AuthorizationCodeGrantService.java
(original)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/services/AuthorizationCodeGrantService.java
Mon Feb 27 17:50:21 2012
@@ -48,6 +48,7 @@ import org.apache.cxf.rs.security.oauth.
import
org.apache.cxf.rs.security.oauth.grants.code.AuthorizationCodeRegistration;
import
org.apache.cxf.rs.security.oauth.grants.code.ServerAuthorizationCodeGrant;
import org.apache.cxf.rs.security.oauth.provider.OAuthServiceException;
+import org.apache.cxf.rs.security.oauth.utils.OAuthConstants;
import org.apache.cxf.security.LoginSecurityContext;
@@ -61,22 +62,8 @@ import org.apache.cxf.security.LoginSecu
@Path("/authorize")
public class AuthorizationCodeGrantService extends AbstractOAuthService {
- private static final String SUPPORTED_RESPONSE_TYPE = "code";
- private static final String REDIRECT_URI = "redirect_uri";
- private static final String SCOPE = "scope";
- private static final String STATE = "state";
-
- private static final String UNSUPPORTED_RESPONSE_TYPE =
"unsupported_response_type";
- private static final String UNAUTHORIZED_CLIENT = "unauthorized_client";
- private static final String INVALID_SCOPE = "invalid_scope";
- private static final String ACCESS_DENIED = "access_denied";
-
private static final long DEFAULT_CODE_GRANT_LIFETIME = 3600L;
- private static final String SESSION_AUTHENTICITY_TOKEN =
"session_authenticity_token";
- private static final String AUTHORIZATION_DECISION_KEY = "oauthDecision";
- private static final String AUTHORIZATION_DECISION_ALLOW = "allow";
-
private long grantLifetime = DEFAULT_CODE_GRANT_LIFETIME;
@GET
@@ -102,21 +89,22 @@ public class AuthorizationCodeGrantServi
protected Response startAuthorization(MultivaluedMap<String, String>
params) {
Client client = getClient(params);
- String redirectUri = validateRedirectUri(client,
params.getFirst(REDIRECT_URI));
+ String redirectUri = validateRedirectUri(client,
params.getFirst(OAuthConstants.REDIRECT_URI));
if (!client.isConfidential()) {
- return createErrorResponse(params, redirectUri,
UNAUTHORIZED_CLIENT);
+ return createErrorResponse(params, redirectUri,
OAuthConstants.UNAUTHORIZED_CLIENT);
}
- if (params.getFirst(SUPPORTED_RESPONSE_TYPE) == null) {
- return createErrorResponse(params, redirectUri,
UNSUPPORTED_RESPONSE_TYPE);
+ String responseType = params.getFirst(OAuthConstants.RESPONSE_TYPE);
+ if (responseType == null ||
!responseType.equals(OAuthConstants.CODE_RESPONSE_TYPE)) {
+ return createErrorResponse(params, redirectUri,
OAuthConstants.UNSUPPORTED_RESPONSE_TYPE);
}
List<OAuthPermission> permissions = null;
try {
- List<String> list = parseScope(params.getFirst(SCOPE));
+ List<String> list =
parseScope(params.getFirst(OAuthConstants.SCOPE));
permissions = ((AuthorizationCodeDataProvider)getDataProvider())
.convertScopeToPermissions(list);
} catch (OAuthServiceException ex) {
- return createErrorResponse(params, redirectUri, INVALID_SCOPE);
+ return createErrorResponse(params, redirectUri,
OAuthConstants.INVALID_SCOPE);
}
OAuthAuthorizationData data =
createAuthorizationData(client, params, permissions);
@@ -147,32 +135,36 @@ public class AuthorizationCodeGrantServi
secData.setProposedScope(sb.toString());
secData.setClientId(client.getClientId());
- secData.setRedirectUri(params.getFirst(REDIRECT_URI));
- secData.setState(params.getFirst(STATE));
+ secData.setRedirectUri(params.getFirst(OAuthConstants.REDIRECT_URI));
+ secData.setState(params.getFirst(OAuthConstants.STATE));
secData.setApplicationName(client.getApplicationName());
secData.setApplicationWebUri(client.getApplicationWebUri());
secData.setApplicationDescription(client.getApplicationDescription());
secData.setApplicationLogoUri(client.getApplicationLogoUri());
+ String replyTo = getMessageContext().getUriInfo()
+ .getAbsolutePathBuilder().path("decision").build().toString();
+ secData.setReplyTo(replyTo);
+
return secData;
}
protected Response completeAuthorization(MultivaluedMap<String, String>
params) {
- if
(!compareRequestAndSessionTokens(params.getFirst(SESSION_AUTHENTICITY_TOKEN))) {
+ if
(!compareRequestAndSessionTokens(params.getFirst(OAuthConstants.SESSION_AUTHENTICITY_TOKEN)))
{
throw new WebApplicationException(400);
}
Client client = getClient(params);
- String originalRedirectUri = params.getFirst(REDIRECT_URI);
+ String originalRedirectUri =
params.getFirst(OAuthConstants.REDIRECT_URI);
String actualRedirectUri = validateRedirectUri(client,
originalRedirectUri);
- String decision = params.getFirst(AUTHORIZATION_DECISION_KEY);
- boolean allow = AUTHORIZATION_DECISION_ALLOW.equals(decision);
+ String decision =
params.getFirst(OAuthConstants.AUTHORIZATION_DECISION_KEY);
+ boolean allow =
OAuthConstants.AUTHORIZATION_DECISION_ALLOW.equals(decision);
if (!allow) {
- return createErrorResponse(params, actualRedirectUri,
ACCESS_DENIED);
+ return createErrorResponse(params, actualRedirectUri,
OAuthConstants.ACCESS_DENIED);
}
AuthorizationCodeRegistration codeReg = new
AuthorizationCodeRegistration();
@@ -182,18 +174,18 @@ public class AuthorizationCodeGrantServi
codeReg.setLifetime(grantLifetime);
codeReg.setIssuedAt(System.currentTimeMillis() / 1000);
- List<String> requestedScope = parseScope(params.getFirst(SCOPE));
+ List<String> requestedScope =
parseScope(params.getFirst(OAuthConstants.SCOPE));
codeReg.setRequestedScope(requestedScope);
List<String> approvedScope = new LinkedList<String>();
for (String rScope : requestedScope) {
String param = params.getFirst(rScope + "_status");
- if (param != null && AUTHORIZATION_DECISION_ALLOW.equals(param)) {
+ if (param != null &&
OAuthConstants.AUTHORIZATION_DECISION_ALLOW.equals(param)) {
approvedScope.add(rScope);
}
}
if (!requestedScope.containsAll(approvedScope)) {
- return createErrorResponse(params, actualRedirectUri,
INVALID_SCOPE);
+ return createErrorResponse(params, actualRedirectUri,
OAuthConstants.INVALID_SCOPE);
}
// the decision was allow but the approved scopes end up being empty
// in this case we default to the requestedScope
@@ -218,10 +210,10 @@ public class AuthorizationCodeGrantServi
try {
grant =
((AuthorizationCodeDataProvider)getDataProvider()).createCodeGrant(codeReg);
} catch (OAuthServiceException ex) {
- return createErrorResponse(params, actualRedirectUri,
ACCESS_DENIED);
+ return createErrorResponse(params, actualRedirectUri,
OAuthConstants.ACCESS_DENIED);
}
- UriBuilder ub = getRedirectUriBuilder(params.getFirst(STATE),
actualRedirectUri);
+ UriBuilder ub =
getRedirectUriBuilder(params.getFirst(OAuthConstants.STATE), actualRedirectUri);
ub.queryParam("code", grant.getCode());
return Response.seeOther(ub.build()).build();
}
@@ -229,7 +221,7 @@ public class AuthorizationCodeGrantServi
protected Response createErrorResponse(MultivaluedMap<String, String>
params,
String redirectUri,
String error) {
- UriBuilder ub = getRedirectUriBuilder(params.getFirst(STATE),
redirectUri);
+ UriBuilder ub =
getRedirectUriBuilder(params.getFirst(OAuthConstants.STATE), redirectUri);
ub.queryParam("error", error);
return Response.seeOther(ub.build()).build();
}
@@ -250,7 +242,7 @@ public class AuthorizationCodeGrantServi
private UriBuilder getRedirectUriBuilder(String state, String redirectUri)
{
UriBuilder ub = UriBuilder.fromUri(redirectUri);
if (state != null) {
- ub.queryParam(STATE, state);
+ ub.queryParam(OAuthConstants.STATE, state);
}
return ub;
}
@@ -261,7 +253,7 @@ public class AuthorizationCodeGrantServi
if (redirectUri != null) {
String webUri = client.getApplicationWebUri();
if (uris.size() > 0 && !uris.contains(redirectUri)
- || webUri != null && !webUri.startsWith(redirectUri)) {
+ || webUri != null && !redirectUri.startsWith(webUri)) {
redirectUri = null;
}
} else if (uris.size() == 1) {
@@ -277,18 +269,18 @@ public class AuthorizationCodeGrantServi
HttpSession session =
getMessageContext().getHttpServletRequest().getSession();
String value = UUID.randomUUID().toString();
secData.setAuthenticityToken(value);
- session.setAttribute(SESSION_AUTHENTICITY_TOKEN, value);
+ session.setAttribute(OAuthConstants.SESSION_AUTHENTICITY_TOKEN, value);
}
private boolean compareRequestAndSessionTokens(String requestToken) {
HttpSession session =
getMessageContext().getHttpServletRequest().getSession();
- String sessionToken =
(String)session.getAttribute(SESSION_AUTHENTICITY_TOKEN);
+ String sessionToken =
(String)session.getAttribute(OAuthConstants.SESSION_AUTHENTICITY_TOKEN);
if (StringUtils.isEmpty(sessionToken)) {
return false;
}
- session.removeAttribute(SESSION_AUTHENTICITY_TOKEN);
+ session.removeAttribute(OAuthConstants.SESSION_AUTHENTICITY_TOKEN);
return requestToken.equals(sessionToken);
}
}
Modified:
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/utils/OAuthConstants.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/utils/OAuthConstants.java?rev=1294248&r1=1294247&r2=1294248&view=diff
==============================================================================
---
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/utils/OAuthConstants.java
(original)
+++
cxf/trunk/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth/utils/OAuthConstants.java
Mon Feb 27 17:50:21 2012
@@ -23,6 +23,41 @@ package org.apache.cxf.rs.security.oauth
* Miscellaneous constants
*/
public final class OAuthConstants {
+ // Common OAuth2 constants
+ public static final String CLIENT_ID = "client_id";
+ public static final String CLIENT_SECRET = "client_secret";
+ public static final String REDIRECT_URI = "redirect_uri";
+ public static final String SCOPE = "scope";
+ public static final String STATE = "state";
+ public static final String ACCESS_TOKEN = "access_token";
+ public static final String ACCESS_TOKEN_TYPE = "token_type";
+ public static final String GRANT_TYPE = "grant_type";
+ public static final String RESPONSE_TYPE = "response_type";
+ public static final String TOKEN_RESPONSE_TYPE = "token";
+
+ // Authorization Code Grant
+ public static final String AUTHORIZATION_CODE_GRANT = "authorization_code";
+ public static final String AUTHORIZATION_CODE_VALUE = "code";
+ public static final String CODE_RESPONSE_TYPE = "code";
+ public static final String SESSION_AUTHENTICITY_TOKEN =
"session_authenticity_token";
+ public static final String AUTHORIZATION_DECISION_KEY = "oauthDecision";
+ public static final String AUTHORIZATION_DECISION_ALLOW = "allow";
+ public static final String AUTHORIZATION_DECISION_DENY = "deny";
+
+ // Error constants
+ public static final String ERROR_KEY = "error";
+ public static final String ERROR_DESCRIPTION_KEY = "error_description";
+
+ public static final String SERVER_ERROR = "server_error";
+ public static final String INVALID_REQUEST = "invalid_request";
+ public static final String INVALID_GRANT = "invalid_grant";
+ public static final String UNSUPPORTED_GRANT_TYPE =
"unsupported_grant_type";
+ public static final String UNSUPPORTED_RESPONSE_TYPE =
"unsupported_response_type";
+ public static final String UNAUTHORIZED_CLIENT = "unauthorized_client";
+ public static final String INVALID_SCOPE = "invalid_scope";
+ public static final String ACCESS_DENIED = "access_denied";
+
private OAuthConstants() {
}
+
}