You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2014/10/21 13:37:17 UTC

git commit: Adding an initial JAAS LoginModule for the STS

Repository: cxf
Updated Branches:
  refs/heads/master 70c985948 -> b3f889334


Adding an initial JAAS LoginModule for the STS


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

Branch: refs/heads/master
Commit: b3f8893340a214823fa2ad126afd14f4dddce13e
Parents: 70c9859
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Tue Oct 21 12:35:43 2014 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Tue Oct 21 12:36:05 2014 +0100

----------------------------------------------------------------------
 .../cxf/ws/security/trust/STSLoginModule.java   | 194 +++++++++++++++++++
 services/sts/systests/basic/pom.xml             |   7 +
 .../sts/deployment/CustomClaimsHandler.java     |   6 +-
 .../systest/sts/jaas/DoubleItPortTypeImpl.java  |  36 ++++
 .../apache/cxf/systest/sts/jaas/JAASTest.java   | 125 +++++++++++-
 .../apache/cxf/systest/sts/jaas/cxf-service.xml |  34 ++--
 .../org/apache/cxf/systest/sts/jaas/jaxrs.xml   |  26 +++
 .../systests/basic/src/test/resources/sts.jaas  |   4 +
 8 files changed, 414 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/b3f88933/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSLoginModule.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSLoginModule.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSLoginModule.java
new file mode 100644
index 0000000..fbf1f1e
--- /dev/null
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSLoginModule.java
@@ -0,0 +1,194 @@
+/**
+ * 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.ws.security.trust;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import org.w3c.dom.Document;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.security.SimplePrincipal;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.PhaseInterceptorChain;
+import org.apache.cxf.rt.security.claims.ClaimCollection;
+import org.apache.cxf.rt.security.saml.SAMLUtils;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
+import org.apache.wss4j.common.saml.SamlAssertionWrapper;
+import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.handler.RequestData;
+import org.apache.wss4j.dom.message.token.UsernameToken;
+import org.apache.wss4j.dom.validate.Credential;
+
+/**
+ * A JAAS LoginModule for authenticating a Username/Password to the STS. The 
+ * STSClient object itself must be configured separately and picked up either via 
+ * the endpoint name or else as the "default" STSClient.
+ */
+public class STSLoginModule implements LoginModule {
+    /**
+     * Whether we require roles or not from the STS. If this is not set then the 
+     * WS-Trust validate binding is used. If it is set then the issue binding is 
+     * used, where the Username + Password credentials are passed via "OnBehalfOf".
+     */
+    public static final String REQUIRE_ROLES = "require.roles";
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(STSLoginModule.class);
+    
+    private Set<Principal> principals = new HashSet<Principal>();
+    private Subject subject;
+    private CallbackHandler callbackHandler;
+    private boolean requireRoles;
+    
+    @Override
+    public void initialize(Subject subj, CallbackHandler cbHandler, Map<String, ?> sharedState,
+                           Map<String, ?> options) {
+        subject = subj;
+        callbackHandler = cbHandler;
+        if (options.containsKey(REQUIRE_ROLES)) {
+            requireRoles = Boolean.parseBoolean((String)options.get(REQUIRE_ROLES));
+        }
+    }
+
+    @Override
+    public boolean login() throws LoginException {
+        // Get username and password
+        Callback[] callbacks = new Callback[2];
+        callbacks[0] = new NameCallback("Username: ");
+        callbacks[1] = new PasswordCallback("Password: ", false);
+
+        try {
+            callbackHandler.handle(callbacks);
+        } catch (IOException ioException) {
+            throw new LoginException(ioException.getMessage());
+        } catch (UnsupportedCallbackException unsupportedCallbackException) {
+            throw new LoginException(unsupportedCallbackException.getMessage() 
+                                     + " not available to obtain information from user.");
+        }
+
+        String user = ((NameCallback) callbacks[0]).getName();
+
+        char[] tmpPassword = ((PasswordCallback) callbacks[1]).getPassword();
+        if (tmpPassword == null) {
+            tmpPassword = new char[0];
+        }
+        String password = new String(tmpPassword);
+        
+        principals = new HashSet<Principal>();
+        
+        STSTokenValidator validator = new STSTokenValidator(true);
+        validator.setUseIssueBinding(requireRoles);
+        
+        // Authenticate token
+        try {
+            UsernameToken token = convertToToken(user, password);
+            Credential credential = new Credential();
+            credential.setUsernametoken(token);
+            
+            RequestData data = new RequestData();
+            Message message = PhaseInterceptorChain.getCurrentMessage();
+            data.setMsgContext(message);
+            credential = validator.validate(credential, data);
+
+            // Add user principal
+            principals.add(new SimplePrincipal(user));
+            
+            // Add roles if a SAML Assertion was returned from the STS
+            principals.addAll(getRoles(message, credential));
+        } catch (Exception e) {
+            LOG.log(Level.INFO, "User " + user + "authentication failed", e);
+            throw new LoginException("User " + user + " authentication failed: " + e.getMessage());
+        }
+        
+        return true;
+    }
+
+    private UsernameToken convertToToken(String username, String password) 
+        throws Exception {
+
+        Document doc = DOMUtils.createDocument();
+        UsernameToken token = new UsernameToken(false, doc, 
+                                                WSConstants.PASSWORD_TEXT);
+        token.setName(username);
+        token.setPassword(password);
+        return token;
+    }
+    
+    private Set<Principal> getRoles(Message msg, Credential credential) {
+        SamlAssertionWrapper samlAssertion = credential.getTransformedToken();
+        if (samlAssertion == null) {
+            samlAssertion = credential.getSamlAssertion();
+        }
+        if (samlAssertion != null) {
+            String roleAttributeName = 
+                (String)msg.getContextualProperty(SecurityConstants.SAML_ROLE_ATTRIBUTENAME);
+            if (roleAttributeName == null || roleAttributeName.length() == 0) {
+                roleAttributeName = WSS4JInInterceptor.SAML_ROLE_ATTRIBUTENAME_DEFAULT;
+            }
+
+            ClaimCollection claims = 
+                SAMLUtils.getClaims((SamlAssertionWrapper)samlAssertion);
+            return SAMLUtils.parseRolesFromClaims(claims, roleAttributeName, null);
+        }
+        
+        return Collections.emptySet();
+    }
+
+    
+    @Override
+    public boolean commit() throws LoginException {
+        if (principals.isEmpty()) {
+            return false;
+        }
+        subject.getPrincipals().addAll(principals);
+        return true;
+    }
+
+    @Override
+    public boolean abort() throws LoginException {
+        return true;
+    }
+
+    @Override
+    public boolean logout() throws LoginException {
+        subject.getPrincipals().removeAll(principals);
+        principals.clear();
+        return true;
+    }
+    
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/b3f88933/services/sts/systests/basic/pom.xml
----------------------------------------------------------------------
diff --git a/services/sts/systests/basic/pom.xml b/services/sts/systests/basic/pom.xml
index 09ff985..70ca271 100644
--- a/services/sts/systests/basic/pom.xml
+++ b/services/sts/systests/basic/pom.xml
@@ -50,6 +50,12 @@
         </dependency>
         <dependency>
             <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-rs-client</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
             <artifactId>cxf-rt-frontend-jaxws</artifactId>
             <version>${project.version}</version>
             <scope>test</scope>
@@ -164,6 +170,7 @@
                             <systemPropertyVariables>
                                 <sts.deployment>standalone</sts.deployment>
                                 <java.io.tmpdir>${basedir}/target/tmp</java.io.tmpdir>
+                                <java.security.auth.login.config>src/test/resources/sts.jaas</java.security.auth.login.config>
                             </systemPropertyVariables>
                         </configuration>
                     </plugin>

http://git-wip-us.apache.org/repos/asf/cxf/blob/b3f88933/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/deployment/CustomClaimsHandler.java
----------------------------------------------------------------------
diff --git a/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/deployment/CustomClaimsHandler.java b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/deployment/CustomClaimsHandler.java
index d77b355..03abf85 100644
--- a/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/deployment/CustomClaimsHandler.java
+++ b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/deployment/CustomClaimsHandler.java
@@ -52,7 +52,11 @@ public class CustomClaimsHandler implements ClaimsHandler {
                 claim.setIssuer("Test Issuer");
                 claim.setOriginalIssuer("Original Issuer");
                 if (ROLE.equals(requestClaim.getClaimType())) {
-                    claim.addValue("admin-user");
+                    if ("alice".equals(parameters.getPrincipal().getName())) {
+                        claim.addValue("admin-user");
+                    } else {
+                        claim.addValue("ordinary-user");
+                    }
                 } else if (GIVEN_NAME.equals(requestClaim.getClaimType())) {
                     claim.addValue(parameters.getPrincipal().getName());
                 } else if (LANGUAGE.equals(requestClaim.getClaimType())) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/b3f88933/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/jaas/DoubleItPortTypeImpl.java
----------------------------------------------------------------------
diff --git a/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/jaas/DoubleItPortTypeImpl.java b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/jaas/DoubleItPortTypeImpl.java
new file mode 100644
index 0000000..deb0b32
--- /dev/null
+++ b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/jaas/DoubleItPortTypeImpl.java
@@ -0,0 +1,36 @@
+/**
+ * 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.systest.sts.jaas;
+
+import javax.jws.WebService;
+
+import org.apache.cxf.feature.Features;
+import org.example.contract.doubleit.DoubleItPortType;
+
+@WebService(targetNamespace = "http://www.example.org/contract/DoubleIt", 
+            serviceName = "DoubleItService", 
+            endpointInterface = "org.example.contract.doubleit.DoubleItPortType")
+@Features(features = "org.apache.cxf.feature.LoggingFeature")              
+public class DoubleItPortTypeImpl implements DoubleItPortType {
+    
+    public int doubleIt(int numberToDouble) {
+        return numberToDouble * 2;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/b3f88933/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/jaas/JAASTest.java
----------------------------------------------------------------------
diff --git a/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/jaas/JAASTest.java b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/jaas/JAASTest.java
index 348b5e8..c02705f 100644
--- a/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/jaas/JAASTest.java
+++ b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/jaas/JAASTest.java
@@ -20,12 +20,14 @@ package org.apache.cxf.systest.sts.jaas;
 
 import java.net.URL;
 
+import javax.ws.rs.WebApplicationException;
 import javax.xml.namespace.QName;
 import javax.xml.ws.BindingProvider;
 import javax.xml.ws.Service;
 
 import org.apache.cxf.Bus;
 import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.cxf.systest.sts.common.SecurityTestUtil;
 import org.apache.cxf.systest.sts.deployment.STSServer;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
@@ -34,10 +36,12 @@ import org.example.contract.doubleit.DoubleItPortType;
 import org.junit.BeforeClass;
 
 /**
- * This tests JAAS authentication to the STS. The service has a UsernameToken policy.
- * The client sends a WS-Security UsernameToken, and it is dispatches to the STS for
- * validation via JAAS. The service also asks for a SAML Token with roles enabled in it,
- * and these roles are stored in the security context for authorization.
+ * This tests JAAS authentication to the STS. A Username + Password extracted from either
+ * a WS-Security UsernameToken for the JAX-WS service, or via HTTP/BA for a JAX-RS service, 
+ * is dispatches to the STS for validation via JAAS. 
+ * 
+ * The service also asks for a SAML Token with roles enabled in it, and these roles 
+ * are stored in the security context for authorization.
  */
 public class JAASTest extends AbstractBusClientServerTestBase {
     
@@ -63,6 +67,7 @@ public class JAASTest extends AbstractBusClientServerTestBase {
                    // set this to false to fork
                    launchServer(STSServer.class, true)
         );
+        
     }
     
     @org.junit.AfterClass
@@ -72,7 +77,7 @@ public class JAASTest extends AbstractBusClientServerTestBase {
     }
 
     @org.junit.Test
-    public void testSuccessfulAuthentication() throws Exception {
+    public void testSuccessfulInvocation() throws Exception {
 
         SpringBusFactory bf = new SpringBusFactory();
         URL busFile = JAASTest.class.getResource("cxf-client.xml");
@@ -95,12 +100,122 @@ public class JAASTest extends AbstractBusClientServerTestBase {
         
         doubleIt(utPort, 25);
         
+        // Note that the UsernameToken should be cached for the second invocation
+        doubleIt(utPort, 35);
+        
+        ((java.io.Closeable)utPort).close();
+        bus.shutdown(true);
+    }
+    
+    @org.junit.Test
+    public void testUnsuccessfulAuthentication() throws Exception {
+
+        SpringBusFactory bf = new SpringBusFactory();
+        URL busFile = JAASTest.class.getResource("cxf-client.xml");
+
+        Bus bus = bf.createBus(busFile.toString());
+        SpringBusFactory.setDefaultBus(bus);
+        SpringBusFactory.setThreadDefaultBus(bus);
+
+        URL wsdl = JAASTest.class.getResource("DoubleIt.wsdl");
+        Service service = Service.create(wsdl, SERVICE_QNAME);
+        QName portQName = new QName(NAMESPACE, "DoubleItUTPort");
+        DoubleItPortType utPort = 
+            service.getPort(portQName, DoubleItPortType.class);
+        updateAddressPort(utPort, PORT);
+        
+        ((BindingProvider)utPort).getRequestContext().put(
+            SecurityConstants.USERNAME, "alice");
+        ((BindingProvider)utPort).getRequestContext().put(
+            SecurityConstants.PASSWORD, "clarinet2");
+        
+        try {
+            doubleIt(utPort, 25);
+            fail("Failure expected on an incorrect password");
+        } catch (Exception ex) {
+            // expected
+        }
+        
+        ((java.io.Closeable)utPort).close();
+        bus.shutdown(true);
+    }
+    
+    @org.junit.Test
+    public void testUnsuccessfulAuthorization() throws Exception {
+
+        SpringBusFactory bf = new SpringBusFactory();
+        URL busFile = JAASTest.class.getResource("cxf-client.xml");
+
+        Bus bus = bf.createBus(busFile.toString());
+        SpringBusFactory.setDefaultBus(bus);
+        SpringBusFactory.setThreadDefaultBus(bus);
+
+        URL wsdl = JAASTest.class.getResource("DoubleIt.wsdl");
+        Service service = Service.create(wsdl, SERVICE_QNAME);
+        QName portQName = new QName(NAMESPACE, "DoubleItUTPort");
+        DoubleItPortType utPort = 
+            service.getPort(portQName, DoubleItPortType.class);
+        updateAddressPort(utPort, PORT);
+        
+        ((BindingProvider)utPort).getRequestContext().put(
+            SecurityConstants.USERNAME, "bob");
+        ((BindingProvider)utPort).getRequestContext().put(
+            SecurityConstants.PASSWORD, "trombone");
+        
+        try {
+            doubleIt(utPort, 25);
+            fail("Failure expected on an incorrect role");
+        } catch (Exception ex) {
+            // expected
+        }
+        
         ((java.io.Closeable)utPort).close();
         bus.shutdown(true);
     }
     
+    @org.junit.Test
+    public void testJAXRSSuccessfulInvocation() throws Exception {
+        doubleIt("alice", "clarinet", false);
+    }
+    
+    @org.junit.Test
+    public void testJAXRSUnsuccessfulAuthentication() throws Exception {
+        doubleIt("alice", "clarinet2", true);
+    }
+    
+    @org.junit.Test
+    public void testJAXRSUnsuccessfulAuthorization() throws Exception {
+        doubleIt("bob", "trombone", true);
+    }
+    
     private static void doubleIt(DoubleItPortType port, int numToDouble) {
         int resp = port.doubleIt(numToDouble);
         assertEquals(numToDouble * 2 , resp);
     }
+    
+    private static void doubleIt(String username, String password, boolean authFailureExpected) {
+        final String configLocation = "org/apache/cxf/systest/sts/jaas/cxf-client.xml";
+        final String address = "https://localhost:" + PORT + "/doubleit/services/doubleit-rs";
+        final int numToDouble = 25;  
+       
+        WebClient client = null;
+        if (username != null && password != null) {
+            client = WebClient.create(address, username, password, configLocation);
+        } else {
+            client = WebClient.create(address, configLocation);
+        }
+        client.type("text/plain").accept("text/plain");
+        try {
+            int resp = client.post(numToDouble, Integer.class);
+            if (authFailureExpected) {
+                throw new RuntimeException("Exception expected");
+            }
+            org.junit.Assert.assertEquals(2 * numToDouble, resp);
+        } catch (WebApplicationException ex) {
+            if (!authFailureExpected) {
+                throw new RuntimeException("Unexpected exception");
+            }
+            org.junit.Assert.assertEquals(500, ex.getResponse().getStatus());
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/b3f88933/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/jaas/cxf-service.xml
----------------------------------------------------------------------
diff --git a/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/jaas/cxf-service.xml b/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/jaas/cxf-service.xml
index baf1f07..bf7ee15 100644
--- a/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/jaas/cxf-service.xml
+++ b/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/jaas/cxf-service.xml
@@ -17,13 +17,15 @@
  specific language governing permissions and limitations
  under the License.
 -->
-<beans xmlns="http://www.springframework.org/schema/beans" xmlns:cxf="http://cxf.apache.org/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:http="http://cxf.apache.org/transports/http/configuration" xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="             http://cxf.apache.org/core             http://cxf.apache.org/schemas/core.xsd             http://cxf.apache.org/configuration/security             http://cxf.apache.org/schemas/configuration/security.xsd             http://cxf.apache.org/jaxws             http://cxf.apache.org/schemas/jaxws.xsd             http://cxf.apache.org/transports/http/configuration             http://cxf.apache.org/schemas/configuration/http-conf.xsd             http://cxf.apache.org/transports/http-jetty/configuration             http://cxf.apache.org/schemas/configuration/http-jetty.xsd      
        http://www.springframework.org/schema/beans             http://www.springframework.org/schema/beans/spring-beans.xsd">
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:cxf="http://cxf.apache.org/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:http="http://cxf.apache.org/transports/http/configuration" xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xsi:schemaLocation="             http://cxf.apache.org/core             http://cxf.apache.org/schemas/core.xsd             http://cxf.apache.org/configuration/security             http://cxf.apache.org/schemas/configuration/security.xsd             http://cxf.apache.org/jaxws             http://cxf.apache.org/schemas/jaxws.xsd       http://cxf.apache.org/jaxrs             http://cxf.apache.org/schemas/jaxrs.xsd      http://cxf.apache.org/transports/http/configuration             http://cxf.apache.org/schemas/configuration/http-conf.xsd             http://cxf.ap
 ache.org/transports/http-jetty/configuration             http://cxf.apache.org/schemas/configuration/http-jetty.xsd             http://www.springframework.org/schema/beans             http://www.springframework.org/schema/beans/spring-beans.xsd">
     <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
     
    <bean id="roleClaimsCallbackHandler" 
          class="org.apache.cxf.systest.sts.jaas.ClaimsCallbackHandler" />
     
-   <bean id="stsClient" class="org.apache.cxf.ws.security.trust.STSClient">
+   <bean id="stsClient" class="org.apache.cxf.ws.security.trust.STSClient"
+        name="default.sts-client"
+        abstract="true">
         <constructor-arg ref="cxf"/>
         <property name="wsdlLocation" value="https://localhost:${testutil.ports.STSServer}/SecurityTokenService/Transport?wsdl"/>
         <property name="serviceName" value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService"/>
@@ -37,6 +39,8 @@
         <property name="claimsCallbackHandler" ref="roleClaimsCallbackHandler"/>
         <property name="tokenType" 
                   value="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"/>
+        <property name="keyType"
+                  value="http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer"/>
    </bean>
     
     <bean id="authorizationInterceptor" 
@@ -48,23 +52,29 @@
        </property>
     </bean>
     
-    <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt" id="doubleitut" implementor="org.apache.cxf.systest.sts.common.DoubleItPortTypeImpl" endpointName="s:DoubleItUTPort" serviceName="s:DoubleItService" depends-on="ClientAuthHttpsSettings" address="https://localhost:${testutil.ports.Server}/doubleit/services/doubleitut" wsdlLocation="org/apache/cxf/systest/sts/jaas/DoubleIt.wsdl">
+    <bean id="authenticationInterceptor" class="org.apache.cxf.interceptor.security.JAASLoginInterceptor">
+        <property name="contextName" value="sts"/>
+    </bean>
+    
+    <!-- JAX-WS service -->
+    <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt" id="doubleitut" implementor="org.apache.cxf.systest.sts.jaas.DoubleItPortTypeImpl" endpointName="s:DoubleItUTPort" serviceName="s:DoubleItService" depends-on="ClientAuthHttpsSettings" address="https://localhost:${testutil.ports.Server}/doubleit/services/doubleitut" wsdlLocation="org/apache/cxf/systest/sts/jaas/DoubleIt.wsdl">
         <jaxws:properties>
-            <entry key="ws-security.ut.validator">
-                <bean class="org.apache.cxf.ws.security.trust.STSTokenValidator">
-                    <constructor-arg value="true"/>
-                    <property name="useIssueBinding" value="true"/>
-                </bean>
-            </entry>
-            <entry key="ws-security.sts.client">
-                <ref bean="stsClient"/>
-            </entry>
+            <entry key="ws-security.validate.token" value="false"/>
         </jaxws:properties>
         <jaxws:inInterceptors>
+            <ref bean="authenticationInterceptor"/>
             <ref bean="authorizationInterceptor"/>
         </jaxws:inInterceptors>
     </jaxws:endpoint>
     
+    <!-- JAX-RS service -->
+    <jaxrs:server modelRef="classpath:org/apache/cxf/systest/sts/jaas/jaxrs.xml" depends-on="ClientAuthHttpsSettings" address="https://localhost:${testutil.ports.Server}/doubleit/services/doubleit-rs">
+        <jaxrs:inInterceptors>
+            <ref bean="authenticationInterceptor"/>
+            <ref bean="authorizationInterceptor"/>
+        </jaxrs:inInterceptors>
+    </jaxrs:server>
+    
     <httpj:engine-factory id="ClientAuthHttpsSettings" bus="cxf">
         <httpj:engine port="${testutil.ports.Server}">
             <httpj:tlsServerParameters>

http://git-wip-us.apache.org/repos/asf/cxf/blob/b3f88933/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/jaas/jaxrs.xml
----------------------------------------------------------------------
diff --git a/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/jaas/jaxrs.xml b/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/jaas/jaxrs.xml
new file mode 100644
index 0000000..be4cd6e
--- /dev/null
+++ b/services/sts/systests/basic/src/test/resources/org/apache/cxf/systest/sts/jaas/jaxrs.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<model xmlns="http://cxf.apache.org/jaxrs">
+    <resource name="org.apache.cxf.systest.sts.jaas.DoubleItPortTypeImpl" path="/">
+        <operation name="doubleIt" verb="POST" path="/" consumes="text/plain" produces="text/plain">
+            <param name="numberToDouble" type="REQUEST_BODY"/>
+        </operation>
+    </resource>
+</model>

http://git-wip-us.apache.org/repos/asf/cxf/blob/b3f88933/services/sts/systests/basic/src/test/resources/sts.jaas
----------------------------------------------------------------------
diff --git a/services/sts/systests/basic/src/test/resources/sts.jaas b/services/sts/systests/basic/src/test/resources/sts.jaas
new file mode 100644
index 0000000..f1e6c19
--- /dev/null
+++ b/services/sts/systests/basic/src/test/resources/sts.jaas
@@ -0,0 +1,4 @@
+
+sts {
+    org.apache.cxf.ws.security.trust.STSLoginModule required require.roles="true";
+};