Repository: cxf
Updated Branches:
  refs/heads/3.0.x-fixes 90f0da4de -> 855250af1


Updates to OAuth2 code request filters and simplifying the big_query demo code 
(still work in progress)


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

Branch: refs/heads/3.0.x-fixes
Commit: 855250af1e321cd51ec3eccb29d3a8401c1fb53f
Parents: 90f0da4
Author: Sergey Beryozkin <[email protected]>
Authored: Wed May 20 14:35:09 2015 +0100
Committer: Sergey Beryozkin <[email protected]>
Committed: Wed May 20 14:39:55 2015 +0100

----------------------------------------------------------------------
 .../oauth2/client/ClientCodeRequestFilter.java  | 74 ++++++++++++--------
 .../oidc/rp/OidcClientCodeRequestFilter.java    | 24 ++++++-
 .../security/oidc/rp/OidcSecurityContext.java   | 52 ++++++++++++++
 3 files changed, 119 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/855250af/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/ClientCodeRequestFilter.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/ClientCodeRequestFilter.java
 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/ClientCodeRequestFilter.java
index 2a2d298..97577d1 100644
--- 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/ClientCodeRequestFilter.java
+++ 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/ClientCodeRequestFilter.java
@@ -59,16 +59,14 @@ public class ClientCodeRequestFilter implements 
ContainerRequestFilter {
     private OAuthClientUtils.Consumer consumer;
     private ClientCodeStateManager clientStateManager;
     private ClientTokenContextManager clientTokenContextManager;
-    private WebClient accessTokenService;
+    private WebClient accessTokenServiceClient;
     private boolean decodeRequestParameters;
     private long expiryThreshold;
+    private String redirectUri;
     
     @Override
     public void filter(ContainerRequestContext rc) throws IOException {
-        SecurityContext sc = rc.getSecurityContext();
-        if (sc == null || sc.getUserPrincipal() == null) {
-            throw ExceptionUtils.toNotAuthorizedException(null, null);
-        }
+        checkSecurityContextStart(rc.getSecurityContext());
         UriInfo ui = rc.getUriInfo();
         String absoluteRequestUri = ui.getAbsolutePath().toString();
         
@@ -82,7 +80,7 @@ public class ClientCodeRequestFilter implements 
ContainerRequestFilter {
         }
         
         if (!sameUriRedirect && absoluteRequestUri.endsWith(startUri)) {
-            ClientTokenContext request = getClientTokenContext();
+            ClientTokenContext request = getClientTokenContext(rc);
             if (request != null) {
                 setClientCodeRequest(request);
                 if (completeUri != null) {
@@ -90,51 +88,65 @@ public class ClientCodeRequestFilter implements 
ContainerRequestFilter {
                 }
                 return;
             }
-            Response codeResponse = createCodeResponse(rc, sc, ui);
+            Response codeResponse = createCodeResponse(rc,  ui);
             rc.abortWith(codeResponse);
         } else if (absoluteRequestUri.endsWith(completeUri)) {
-            processCodeResponse(rc, sc, ui);
+            processCodeResponse(rc, ui);
+            checkSecurityContextEnd(rc.getSecurityContext());
         }
     }
 
-    private Response createCodeResponse(ContainerRequestContext rc, 
SecurityContext sc, UriInfo ui) {
-        MultivaluedMap<String, String> redirectState = createRedirectState(rc, 
sc, ui);
-        String redirectScope = redirectState.getFirst(OAuthConstants.SCOPE);
+    protected void checkSecurityContextStart(SecurityContext sc) {
+        checkSecurityContextEnd(sc);
+    }
+    private void checkSecurityContextEnd(SecurityContext sc) {
+        if (sc == null || sc.getUserPrincipal() == null) {
+            throw ExceptionUtils.toNotAuthorizedException(null, null);
+        }
+    }
+
+    private Response createCodeResponse(ContainerRequestContext rc, UriInfo 
ui) {
+        MultivaluedMap<String, String> redirectState = createRedirectState(rc, 
ui);
+        String theState = redirectState != null ? 
redirectState.getFirst(OAuthConstants.SCOPE) : null;
+        String redirectScope = redirectState != null ? 
redirectState.getFirst(OAuthConstants.SCOPE) : null;
         String theScope = redirectScope != null ? redirectScope : scopes;
         URI uri = 
OAuthClientUtils.getAuthorizationURI(authorizationServiceUri, 
                                              consumer.getKey(), 
                                              
getAbsoluteRedirectUri(ui).toString(), 
-                                             
redirectState.getFirst(OAuthConstants.STATE), 
+                                             theState, 
                                              theScope);
         return Response.seeOther(uri).build();
     }
 
     private URI getAbsoluteRedirectUri(UriInfo ui) {
-        if (completeUri != null) {
+        if (redirectUri != null) {
+            return URI.create(redirectUri);
+        } else if (completeUri != null) {
             return completeUri.startsWith("http") ? URI.create(completeUri) 
                 : ui.getBaseUriBuilder().path(completeUri).build();
         } else {
             return ui.getAbsolutePath();
         }
     }
-    protected void processCodeResponse(ContainerRequestContext rc, 
SecurityContext sc, UriInfo ui) {
+    protected void processCodeResponse(ContainerRequestContext rc, UriInfo ui) 
{
         MultivaluedMap<String, String> params = toRequestState(rc, ui);
         String codeParam = 
params.getFirst(OAuthConstants.AUTHORIZATION_CODE_VALUE);
         ClientAccessToken at = null;
         if (codeParam != null) {
             AccessTokenGrant grant = new AuthorizationCodeGrant(codeParam, 
getAbsoluteRedirectUri(ui));
-            at = OAuthClientUtils.getAccessToken(accessTokenService, consumer, 
grant);
+            at = OAuthClientUtils.getAccessToken(accessTokenServiceClient, 
consumer, grant);
         }
-        ClientTokenContext tokenContext = initializeClientTokenContext(at, 
params);
+        ClientTokenContext tokenContext = initializeClientTokenContext(rc, at, 
params);
         if (at != null && clientTokenContextManager != null) {
             clientTokenContextManager.setClientTokenContext(mc, tokenContext);
         }
         setClientCodeRequest(tokenContext);
     }
     
-    private ClientTokenContext initializeClientTokenContext(ClientAccessToken 
at, 
+    protected ClientTokenContext 
initializeClientTokenContext(ContainerRequestContext rc, 
+                                                              
ClientAccessToken at, 
                                                             
MultivaluedMap<String, String> params) {
-        ClientTokenContext tokenContext = createTokenContext(at);
+        ClientTokenContext tokenContext = createTokenContext(rc, at);
         ((ClientTokenContextImpl)tokenContext).setToken(at);
         if (clientStateManager != null) {
             MultivaluedMap<String, String> state = 
clientStateManager.fromRedirectState(mc, params);
@@ -145,7 +157,7 @@ public class ClientCodeRequestFilter implements 
ContainerRequestFilter {
         
     }
 
-    protected ClientTokenContext createTokenContext(ClientAccessToken at) {
+    protected ClientTokenContext createTokenContext(ContainerRequestContext 
rc, ClientAccessToken at) {
         return new ClientTokenContextImpl();
     }
     
@@ -153,8 +165,7 @@ public class ClientCodeRequestFilter implements 
ContainerRequestFilter {
         JAXRSUtils.getCurrentMessage().setContent(ClientTokenContext.class, 
request);
     }
 
-    private MultivaluedMap<String, String> 
createRedirectState(ContainerRequestContext rc, SecurityContext sc, 
-                                                               UriInfo ui) {
+    private MultivaluedMap<String, String> 
createRedirectState(ContainerRequestContext rc, UriInfo ui) {
         if (clientStateManager == null) {
             return null;
         }
@@ -180,10 +191,10 @@ public class ClientCodeRequestFilter implements 
ContainerRequestFilter {
             }
             sb.append(s);
         }
-        setScopeString(sb.toString());
+        setScopes(sb.toString());
     }
-    public void setScopeString(String scopesString) {
-        this.scopes = scopesString;
+    public void setScopes(String scopes) {
+        this.scopes = scopes;
     }
 
     public void setStartUri(String relStartUri) {
@@ -198,8 +209,8 @@ public class ClientCodeRequestFilter implements 
ContainerRequestFilter {
         this.completeUri = completeUri;
     }
 
-    public void setAccessTokenService(WebClient accessTokenService) {
-        this.accessTokenService = accessTokenService;
+    public void setAccessTokenServiceClient(WebClient 
accessTokenServiceClient) {
+        this.accessTokenServiceClient = accessTokenServiceClient;
     }
 
     public void setClientCodeStateManager(ClientCodeStateManager manager) {
@@ -221,7 +232,7 @@ public class ClientCodeRequestFilter implements 
ContainerRequestFilter {
         this.decodeRequestParameters = decodeRequestParameters;
     }
 
-    private ClientTokenContext getClientTokenContext() {
+    protected ClientTokenContext getClientTokenContext(ContainerRequestContext 
rc) {
         ClientTokenContext ctx = null;
         if (clientTokenContextManager != null) {
             ctx = clientTokenContextManager.getClientTokenContext(mc);
@@ -229,7 +240,7 @@ public class ClientCodeRequestFilter implements 
ContainerRequestFilter {
                 ClientAccessToken newAt = 
refreshAccessTokenIfExpired(ctx.getToken());
                 if (newAt != null) {
                     clientTokenContextManager.removeClientTokenContext(mc, 
ctx);
-                    ClientTokenContext newCtx = 
initializeClientTokenContext(newAt, ctx.getState());            
+                    ClientTokenContext newCtx = 
initializeClientTokenContext(rc, newAt, ctx.getState());            
                     clientTokenContextManager.setClientTokenContext(mc, 
newCtx);
                     ctx = newCtx;
                 }
@@ -242,7 +253,7 @@ public class ClientCodeRequestFilter implements 
ContainerRequestFilter {
         if (at.getRefreshToken() != null
             && ((expiryThreshold > 0 && OAuthUtils.isExpired(at.getIssuedAt(), 
at.getExpiresIn() - expiryThreshold))
             || OAuthUtils.isExpired(at.getIssuedAt(), at.getExpiresIn()))) {
-            return OAuthClientUtils.refreshAccessToken(accessTokenService, 
consumer, at);
+            return 
OAuthClientUtils.refreshAccessToken(accessTokenServiceClient, consumer, at);
         }
         return null;
     }
@@ -250,4 +261,9 @@ public class ClientCodeRequestFilter implements 
ContainerRequestFilter {
     public void setExpiryThreshold(long expiryThreshold) {
         this.expiryThreshold = expiryThreshold;
     }
+
+    public void setRedirectUri(String redirectUri) {
+        // Can be set to something like "postmessage" in some flows
+        this.redirectUri = redirectUri;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/855250af/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java
 
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java
index aba4d3c..57cc2de 100644
--- 
a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java
+++ 
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcClientCodeRequestFilter.java
@@ -18,6 +18,10 @@
  */
 package org.apache.cxf.rs.security.oidc.rp;
 
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.core.SecurityContext;
+
+import org.apache.cxf.jaxrs.utils.ExceptionUtils;
 import org.apache.cxf.rs.security.oauth2.client.ClientCodeRequestFilter;
 import org.apache.cxf.rs.security.oauth2.client.ClientTokenContext;
 import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
@@ -25,16 +29,32 @@ import 
org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
 public class OidcClientCodeRequestFilter extends ClientCodeRequestFilter {
 
     private UserInfoClient userInfoClient;
+    private boolean userInfoRequired = true; 
     @Override
-    protected ClientTokenContext createTokenContext(ClientAccessToken at) {
+    protected ClientTokenContext createTokenContext(ContainerRequestContext 
rc, ClientAccessToken at) {
         OidcClientTokenContextImpl ctx = new OidcClientTokenContextImpl();
         if (at != null) {
             ctx.setIdToken(userInfoClient.getIdToken(at, 
getConsumer().getKey()));
-            ctx.setUserInfo(userInfoClient.getUserInfo(at, ctx.getIdToken()));
+            if (userInfoRequired) {
+                ctx.setUserInfo(userInfoClient.getUserInfo(at, 
ctx.getIdToken()));
+            }
+            rc.setSecurityContext(new OidcSecurityContext(ctx));
         }
+        
         return ctx;
     }
     public void setUserInfoClient(UserInfoClient userInfoClient) {
         this.userInfoClient = userInfoClient;
     }
+    public void setUserInfoRequired(boolean userInfoRequired) {
+        this.userInfoRequired = userInfoRequired;
+    }
+    @Override
+    protected void checkSecurityContextStart(SecurityContext sc) {
+        // The SSO is managed out of band and the act of validating IdToken
+        // finalizes the authentication flow
+        if (sc != null && sc.getUserPrincipal() != null) {
+            throw ExceptionUtils.toNotAuthorizedException(null, null);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/855250af/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcSecurityContext.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcSecurityContext.java
 
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcSecurityContext.java
new file mode 100644
index 0000000..f8b8045
--- /dev/null
+++ 
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcSecurityContext.java
@@ -0,0 +1,52 @@
+/**
+ * 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.oidc.rp;
+
+import javax.ws.rs.core.SecurityContext;
+
+import org.apache.cxf.common.security.SimpleSecurityContext;
+import org.apache.cxf.jaxrs.utils.HttpUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+
+public class OidcSecurityContext extends SimpleSecurityContext implements 
SecurityContext {
+    private OidcClientTokenContext oidcContext;
+    public OidcSecurityContext(OidcClientTokenContext oidcContext) {
+        super(getUserName(oidcContext));
+        this.oidcContext = oidcContext;
+    }
+    public OidcClientTokenContext getOidcContext() {
+        return oidcContext;
+    }
+    private static String getUserName(OidcClientTokenContext oidcContext) {
+        if (oidcContext.getUserInfo() != null) {
+            return oidcContext.getUserInfo().getEmail();
+        } else {
+            return oidcContext.getIdToken().getSubject();
+        }
+    }
+    @Override
+    public boolean isSecure() {
+        String value = 
HttpUtils.getEndpointAddress(JAXRSUtils.getCurrentMessage());
+        return value.startsWith("https://";);
+    }
+    @Override
+    public String getAuthenticationScheme() {
+        return "OIDC";
+    }
+}

Reply via email to