You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2016/01/15 15:31:01 UTC

cxf git commit: [CXF-6686] Prototyping RFC7622 introspection code

Repository: cxf
Updated Branches:
  refs/heads/master e1c60863a -> 0578e1614


[CXF-6686] Prototyping RFC7622 introspection code


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/0578e161
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/0578e161
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/0578e161

Branch: refs/heads/master
Commit: 0578e16146527b0782530c40ba2db17531756d96
Parents: e1c6086
Author: Sergey Beryozkin <sb...@gmail.com>
Authored: Fri Jan 15 14:23:26 2016 +0000
Committer: Sergey Beryozkin <sb...@gmail.com>
Committed: Fri Jan 15 14:23:26 2016 +0000

----------------------------------------------------------------------
 .../oauth2/common/AccessTokenValidation.java    |   7 +
 .../security/oauth2/common/OAuthPermission.java |   4 +
 .../oauth2/common/TokenIntrospection.java       | 127 +++++++++++++++++++
 .../filters/AccessTokenIntrospectionClient.java |  91 +++++++++++++
 .../oauth2/provider/OAuthJSONProvider.java      |  89 ++++++++++++-
 .../services/AccessTokenValidatorService.java   |   4 -
 .../services/TokenIntrospectionService.java     | 105 +++++++++++++++
 .../oauth2/services/TokenRevocationService.java |   4 +-
 .../security/oauth2/utils/OAuthConstants.java   |   6 +-
 9 files changed, 421 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/0578e161/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenValidation.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenValidation.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenValidation.java
index 5fb14a6..508b37f 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenValidation.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/AccessTokenValidation.java
@@ -26,6 +26,13 @@ import java.util.Map;
 import javax.xml.bind.annotation.XmlRootElement;
 
 // Represents the information about the validated ServerAccessToken.
+// It is returned by AccessTokenValidatorService and is checked by CXF OAuthRequestFilter
+// protecting the service resources.
+
+// If the protected resources are not CXF based then use TokenIntrospectionService which
+// returns RFC 7622 compliant TokenIntrospection response. 
+
+
 // The problem with reading specific ServerAccessToken instances is that
 // the (JAXB) reader needs to be specifically aware of the concrete token
 // classes like BearerAccessToken, etc, even though classes like BearerAccessToken

http://git-wip-us.apache.org/repos/asf/cxf/blob/0578e161/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/OAuthPermission.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/OAuthPermission.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/OAuthPermission.java
index 43aeb64..26e7eef 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/OAuthPermission.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/OAuthPermission.java
@@ -45,6 +45,10 @@ public class OAuthPermission implements Serializable {
         
     }
     
+    public OAuthPermission(String permission) {
+        this.permission = permission;
+    }
+    
     public OAuthPermission(String permission, String description) {
         this.description = description;
         this.permission = permission;

http://git-wip-us.apache.org/repos/asf/cxf/blob/0578e161/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/TokenIntrospection.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/TokenIntrospection.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/TokenIntrospection.java
new file mode 100644
index 0000000..4e3911f
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/common/TokenIntrospection.java
@@ -0,0 +1,127 @@
+/**
+ * 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.common;
+
+import java.util.HashMap;
+import java.util.Map;
+
+// RFC 7622 Introspection Response
+public class TokenIntrospection {
+    private boolean active;
+    private String scope;
+    private String clientId;
+    private String username;
+    private String tokenType;
+    private Long iat;
+    private Long exp;
+    private Long nbf;
+    private String sub;
+    private String aud;
+    private String iss;
+    private String jti;
+    
+    private Map<String, String> extensions = new HashMap<String, String>();
+    
+    public TokenIntrospection() {
+        
+    }
+    
+    public TokenIntrospection(boolean active) {
+        this.active = active;
+    }
+
+    public boolean isActive() {
+        return active;
+    }
+    public void setActive(boolean active) {
+        this.active = active;
+    }
+    public String getScope() {
+        return scope;
+    }
+    public void setScope(String scope) {
+        this.scope = scope;
+    }
+    public String getClientId() {
+        return clientId;
+    }
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+    public String getUsername() {
+        return username;
+    }
+    public void setUsername(String username) {
+        this.username = username;
+    }
+    public String getTokenType() {
+        return tokenType;
+    }
+    public void setTokenType(String tokenType) {
+        this.tokenType = tokenType;
+    }
+    public Long getIat() {
+        return iat;
+    }
+    public void setIat(Long iat) {
+        this.iat = iat;
+    }
+    public Long getExp() {
+        return exp;
+    }
+    public void setExp(Long exp) {
+        this.exp = exp;
+    }
+    public Long getNbf() {
+        return nbf;
+    }
+    public void setNbf(Long nbf) {
+        this.nbf = nbf;
+    }
+    public String getSub() {
+        return sub;
+    }
+    public void setSub(String sub) {
+        this.sub = sub;
+    }
+    public String getAud() {
+        return aud;
+    }
+    public void setAud(String aud) {
+        this.aud = aud;
+    }
+    public String getIss() {
+        return iss;
+    }
+    public void setIss(String iss) {
+        this.iss = iss;
+    }
+    public String getJti() {
+        return jti;
+    }
+    public void setJti(String jti) {
+        this.jti = jti;
+    }
+    public Map<String, String> getExtensions() {
+        return extensions;
+    }
+    public void setExtensions(Map<String, String> extensions) {
+        this.extensions = extensions;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/0578e161/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/AccessTokenIntrospectionClient.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/AccessTokenIntrospectionClient.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/AccessTokenIntrospectionClient.java
new file mode 100644
index 0000000..c730c9c
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/filters/AccessTokenIntrospectionClient.java
@@ -0,0 +1,91 @@
+/**
+ * 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.filters;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.rs.security.oauth2.common.AccessTokenValidation;
+import org.apache.cxf.rs.security.oauth2.common.OAuthPermission;
+import org.apache.cxf.rs.security.oauth2.common.TokenIntrospection;
+import org.apache.cxf.rs.security.oauth2.provider.AccessTokenValidator;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+
+public class AccessTokenIntrospectionClient implements AccessTokenValidator {
+
+    private WebClient tokenValidatorClient;
+    public List<String> getSupportedAuthorizationSchemes() {
+        return Collections.singletonList(OAuthConstants.BEARER_AUTHORIZATION_SCHEME);
+    }
+
+    public AccessTokenValidation validateAccessToken(MessageContext mc,
+                                                     String authScheme, 
+                                                     String authSchemeData,
+                                                     MultivaluedMap<String, String> extraProps) 
+        throws OAuthServiceException {
+        WebClient client = WebClient.fromClient(tokenValidatorClient, true);
+        MultivaluedMap<String, String> props = new MetadataMap<String, String>();
+        props.putSingle(OAuthConstants.TOKEN_ID, authSchemeData);
+        try {
+            TokenIntrospection response = client.post(props, TokenIntrospection.class);
+            return convertIntrospectionToValidation(response);
+        } catch (WebApplicationException ex) {
+            throw new OAuthServiceException(ex);
+        }
+    }
+
+    private AccessTokenValidation convertIntrospectionToValidation(TokenIntrospection response) {
+        AccessTokenValidation atv = new AccessTokenValidation();
+        atv.setInitialValidationSuccessful(response.isActive());
+        if (!response.isActive()) {
+            return atv;
+        }
+        atv.setClientId(response.getClientId());
+        atv.setTokenIssuedAt(response.getIat());
+        atv.setTokenLifetime(response.getExp() - response.getIat());
+        atv.setAudience(response.getAud());
+        if (response.getScope() != null) {
+            String[] scopes = response.getScope().split(" ");
+            List<OAuthPermission> perms = new LinkedList<OAuthPermission>();
+            for (String s : scopes) {    
+                if (!StringUtils.isEmpty(s)) {
+                    perms.add(new OAuthPermission(s.trim()));
+                }
+            }
+            atv.setTokenScopes(perms);
+        }
+        
+        return atv;
+    }
+
+    public void setTokenValidatorClient(WebClient tokenValidatorClient) {
+        this.tokenValidatorClient = tokenValidatorClient;
+    }
+    
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/0578e161/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProvider.java
index c850cef..46db726 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProvider.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/OAuthJSONProvider.java
@@ -41,6 +41,7 @@ import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.rs.security.oauth2.client.OAuthClientUtils;
 import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
 import org.apache.cxf.rs.security.oauth2.common.OAuthError;
+import org.apache.cxf.rs.security.oauth2.common.TokenIntrospection;
 import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
 
 @Provider
@@ -54,7 +55,7 @@ public class OAuthJSONProvider implements MessageBodyWriter<Object>,
     }
 
     public boolean isWriteable(Class<?> cls, Type t, Annotation[] anns, MediaType mt) {
-        return cls == ClientAccessToken.class || cls == OAuthError.class;
+        return cls == ClientAccessToken.class || cls == OAuthError.class || cls == TokenIntrospection.class;
     }
     
     public void writeTo(Object obj, Class<?> cls, Type t, Annotation[] anns, MediaType mt,
@@ -62,11 +63,46 @@ public class OAuthJSONProvider implements MessageBodyWriter<Object>,
         WebApplicationException {
         if (obj instanceof ClientAccessToken) {
             writeAccessToken((ClientAccessToken)obj, os);
+        } else if (obj instanceof TokenIntrospection) {
+            writeTokenIntrospection((TokenIntrospection)obj, os);
         } else {
             writeOAuthError((OAuthError)obj, os);
         }
     }
 
+    private void writeTokenIntrospection(TokenIntrospection obj, OutputStream os) throws IOException {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        appendJsonPair(sb, "active", obj.isActive(), false);
+        if (obj.getClientId() != null) {
+            sb.append(",");
+            appendJsonPair(sb, OAuthConstants.CLIENT_ID, obj.getClientId());
+        }
+        if (obj.getUsername() != null) {
+            sb.append(",");
+            appendJsonPair(sb, "username", obj.getUsername());
+        }
+        if (obj.getTokenType() != null) {
+            sb.append(",");
+            appendJsonPair(sb, OAuthConstants.ACCESS_TOKEN_TYPE, obj.getTokenType());
+        }
+        if (obj.getScope() != null) {
+            sb.append(",");
+            appendJsonPair(sb, OAuthConstants.SCOPE, obj.getScope());
+        }
+        if (obj.getAud() != null) {
+            sb.append(",");
+            appendJsonPair(sb, "aud", obj.getAud());
+        }
+        appendJsonPair(sb, "iat", obj.getIat(), false);
+        appendJsonPair(sb, "exp", obj.getExp(), false);
+        sb.append("}");
+        String result = sb.toString();
+        os.write(result.getBytes(StandardCharsets.UTF_8));
+        os.flush();
+        
+    }
+
     private void writeOAuthError(OAuthError obj, OutputStream os) throws IOException {
         StringBuilder sb = new StringBuilder();
         sb.append("{");
@@ -133,7 +169,9 @@ public class OAuthJSONProvider implements MessageBodyWriter<Object>,
     }
     
     public boolean isReadable(Class<?> cls, Type t, Annotation[] anns, MediaType mt) {
-        return Map.class.isAssignableFrom(cls) || ClientAccessToken.class.isAssignableFrom(cls);
+        return Map.class.isAssignableFrom(cls) 
+            || ClientAccessToken.class.isAssignableFrom(cls)
+            || TokenIntrospection.class.isAssignableFrom(cls);
     }
 
     public Object readFrom(Class<Object> cls, Type t, Annotation[] anns, 
@@ -142,16 +180,53 @@ public class OAuthJSONProvider implements MessageBodyWriter<Object>,
         Map<String, String> params = readJSONResponse(is);
         if (Map.class.isAssignableFrom(cls)) {
             return params;
-        }
-        ClientAccessToken token = OAuthClientUtils.fromMapToClientToken(params);
-        if (token == null) {
-            throw new WebApplicationException(500);
+        } else if (ClientAccessToken.class.isAssignableFrom(cls)) {
+            ClientAccessToken token = OAuthClientUtils.fromMapToClientToken(params);
+            if (token == null) {
+                throw new WebApplicationException(500);
+            } else {
+                return token;
+            }
         } else {
-            return token;
+            return fromMapToTokenIntrospection(params);
         }
         
     }
 
+    private Object fromMapToTokenIntrospection(Map<String, String> params) {
+        TokenIntrospection resp = new TokenIntrospection();
+        resp.setActive(Boolean.valueOf(params.get("active")));
+        String clientId = params.get(OAuthConstants.CLIENT_ID);
+        if (clientId != null) {
+            resp.setClientId(clientId);
+        }
+        String username = params.get("username");
+        if (username != null) {
+            resp.setUsername(username);
+        }
+        String scope = params.get(OAuthConstants.SCOPE);
+        if (scope != null) {
+            resp.setScope(scope);
+        }
+        String tokenType = params.get(OAuthConstants.ACCESS_TOKEN_TYPE);
+        if (tokenType != null) {
+            resp.setTokenType(tokenType);
+        }
+        String aud = params.get("aud");
+        if (aud != null) {
+            resp.setAud(aud);
+        }
+        String iat = params.get("iat");
+        if (iat != null) {
+            resp.setIat(Long.valueOf(iat));
+        }
+        String exp = params.get("exp");
+        if (exp != null) {
+            resp.setExp(Long.valueOf(exp));
+        }
+        return resp;
+    }
+
     public Map<String, String> readJSONResponse(InputStream is) throws IOException  {
         String str = IOUtils.readStringFromStream(is).trim();
         if (str.length() == 0) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/0578e161/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AccessTokenValidatorService.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AccessTokenValidatorService.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AccessTokenValidatorService.java
index d87dd2f..496ffd4 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AccessTokenValidatorService.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/AccessTokenValidatorService.java
@@ -76,10 +76,6 @@ public class AccessTokenValidatorService extends AbstractAccessTokenValidator {
         this.blockUnsecureRequests = blockUnsecureRequests;
     }
 
-    public boolean isBlockUnauthorizedRequests() {
-        return blockUnauthorizedRequests;
-    }
-
     public void setBlockUnauthorizedRequests(boolean blockUnauthorizedRequests) {
         this.blockUnauthorizedRequests = blockUnauthorizedRequests;
     }

http://git-wip-us.apache.org/repos/asf/cxf/blob/0578e161/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenIntrospectionService.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenIntrospectionService.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenIntrospectionService.java
new file mode 100644
index 0000000..11485fe
--- /dev/null
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenIntrospectionService.java
@@ -0,0 +1,105 @@
+/**
+ * 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.services;
+
+import java.util.logging.Logger;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Encoded;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.SecurityContext;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
+import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken;
+import org.apache.cxf.rs.security.oauth2.common.TokenIntrospection;
+import org.apache.cxf.rs.security.oauth2.provider.OAuthDataProvider;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthConstants;
+import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils;
+
+@Path("introspect")
+public class TokenIntrospectionService {
+    private static final Logger LOG = LogUtils.getL7dLogger(TokenIntrospectionService.class);
+    private boolean blockUnsecureRequests;
+    private boolean blockUnauthorizedRequests = true;
+    private MessageContext mc;
+    private OAuthDataProvider dataProvider;
+    @POST
+    @Produces({MediaType.APPLICATION_JSON })
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    public TokenIntrospection getTokenIntrospection(@Encoded MultivaluedMap<String, String> params) {
+        checkSecurityContext();
+        String tokenId = params.getFirst(OAuthConstants.TOKEN_ID);
+        ServerAccessToken at = dataProvider.getAccessToken(tokenId);
+        if (at == null || OAuthUtils.isExpired(at.getIssuedAt(), at.getExpiresIn())) { 
+            return new TokenIntrospection(false);
+        }
+        TokenIntrospection response = new TokenIntrospection(true);
+        response.setClientId(at.getClient().getClientId());
+        if (!at.getScopes().isEmpty()) {
+            response.setScope(OAuthUtils.convertPermissionsToScope(at.getScopes()));
+        }
+        if (at.getSubject() != null) {
+            response.setUsername(at.getSubject().getLogin());
+        }
+        if (at.getAudience() != null) {
+            response.setAud(at.getAudience());
+        }
+        response.setIat(at.getIssuedAt());
+        response.setExp(at.getIssuedAt() + at.getExpiresIn());
+        response.setTokenType(at.getTokenType());
+        return response;
+    }
+
+    private void checkSecurityContext() {
+        SecurityContext sc = mc.getSecurityContext();
+        if (!sc.isSecure() && blockUnsecureRequests) {
+            LOG.warning("Unsecure HTTP, Transport Layer Security is recommended");
+            ExceptionUtils.toNotAuthorizedException(null,  null);
+        }
+        if (sc.getUserPrincipal() == null && blockUnauthorizedRequests) {
+            LOG.warning("Authenticated Principal is not available");
+            ExceptionUtils.toNotAuthorizedException(null, null);
+        }
+        
+    }
+
+    public void setBlockUnsecureRequests(boolean blockUnsecureRequests) {
+        this.blockUnsecureRequests = blockUnsecureRequests;
+    }
+
+    public void setBlockUnauthorizedRequests(boolean blockUnauthorizedRequests) {
+        this.blockUnauthorizedRequests = blockUnauthorizedRequests;
+    }
+
+    public void setDataProvider(OAuthDataProvider dataProvider) {
+        this.dataProvider = dataProvider;
+    }
+    
+    @Context
+    public void setMessageContext(MessageContext context) {
+        this.mc = context;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/0578e161/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenRevocationService.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenRevocationService.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenRevocationService.java
index 26be81f..483ffd8 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenRevocationService.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/TokenRevocationService.java
@@ -48,11 +48,11 @@ public class TokenRevocationService extends AbstractTokenService {
         
         // Make sure the client is authenticated
         Client client = authenticateClientIfNeeded(params);
-        String token = params.getFirst(OAuthConstants.REVOKED_TOKEN_ID);
+        String token = params.getFirst(OAuthConstants.TOKEN_ID);
         if (token == null) {
             return createErrorResponse(params, OAuthConstants.UNSUPPORTED_TOKEN_TYPE);
         }
-        String tokenTypeHint = params.getFirst(OAuthConstants.REVOKED_TOKEN_TYPE_HINT);
+        String tokenTypeHint = params.getFirst(OAuthConstants.TOKEN_TYPE_HINT);
         if (tokenTypeHint != null 
             && !OAuthConstants.ACCESS_TOKEN.equals(tokenTypeHint)
             && !OAuthConstants.REFRESH_TOKEN.equals(tokenTypeHint)) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/0578e161/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthConstants.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthConstants.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthConstants.java
index 8a98eff..71d517c 100644
--- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthConstants.java
+++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/OAuthConstants.java
@@ -119,9 +119,9 @@ public final class OAuthConstants {
     public static final String INVALID_SCOPE = "invalid_scope";
     public static final String ACCESS_DENIED = "access_denied";
     
-    // Token Revocation
-    public static final String REVOKED_TOKEN_ID = "token";
-    public static final String REVOKED_TOKEN_TYPE_HINT = "token_type_hint";
+    // Token Revocation, Introspection
+    public static final String TOKEN_ID = "token";
+    public static final String TOKEN_TYPE_HINT = "token_type_hint";
     public static final String UNSUPPORTED_TOKEN_TYPE = "unsupported_token_type";
     
     // Authorization scheme constants, used internally by AccessTokenValidation client and service