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 2010/10/14 18:22:14 UTC
svn commit: r1022599 - in /cxf/trunk:
common/common/src/main/java/org/apache/cxf/common/security/
rt/core/src/main/java/org/apache/cxf/interceptor/security/
rt/core/src/test/java/org/apache/cxf/interceptor/security/
rt/ws/security/src/main/java/org/apa...
Author: sergeyb
Date: Thu Oct 14 16:22:13 2010
New Revision: 1022599
URL: http://svn.apache.org/viewvc?rev=1022599&view=rev
Log:
[CXF-3063] : Initial code for using WSSE tokens for authorization decisions without extending WSS4JInInterceptor
Added:
cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SecurityToken.java (with props)
cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/TokenType.java (with props)
cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/UsernameToken.java (with props)
cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractSecurityContextInInterceptor.java (with props)
cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractUsernameTokenInInterceptor.java (with props)
cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java (with props)
cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java (with props)
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DelegatingCallbackHandler.java (with props)
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java (with props)
cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java (with props)
Removed:
cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/DefaultSecurityContextTest.java
Modified:
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java
cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10Test.java
cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10UsernameAuthorizationTest.java
cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/client/client_restricted_unauthorized.xml
cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/server_restricted_authorized.xml
Added: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SecurityToken.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SecurityToken.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SecurityToken.java (added)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SecurityToken.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,23 @@
+/**
+ * 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.common.security;
+
+public interface SecurityToken {
+ TokenType getTokenType();
+}
Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SecurityToken.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/SecurityToken.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/TokenType.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/TokenType.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/TokenType.java (added)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/TokenType.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,23 @@
+/**
+ * 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.common.security;
+
+public enum TokenType {
+ UsernameToken
+}
Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/TokenType.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/TokenType.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/UsernameToken.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/UsernameToken.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/UsernameToken.java (added)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/UsernameToken.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,71 @@
+/**
+ * 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.common.security;
+
+public class UsernameToken implements SecurityToken {
+
+ private String name;
+ private String password;
+ private String passwordType;
+ private boolean isHashed;
+ private String nonce;
+ private String createdTime;
+
+ public UsernameToken(String name,
+ String password,
+ String passwordType,
+ boolean isHashed,
+ String nonce,
+ String createdTime) {
+ this.name = name;
+ this.password = password;
+ this.passwordType = passwordType;
+ this.isHashed = isHashed;
+ this.nonce = nonce;
+ this.createdTime = createdTime;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String getPasswordType() {
+ return passwordType;
+ }
+
+ public boolean isHashed() {
+ return isHashed;
+ }
+
+ public String getNonce() {
+ return nonce;
+ }
+
+ public String getCreatedTime() {
+ return createdTime;
+ }
+
+ public TokenType getTokenType() {
+ return TokenType.UsernameToken;
+ }
+}
Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/UsernameToken.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/common/common/src/main/java/org/apache/cxf/common/security/UsernameToken.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractSecurityContextInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractSecurityContextInInterceptor.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractSecurityContextInInterceptor.java (added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractSecurityContextInInterceptor.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,79 @@
+/**
+ * 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.interceptor.security;
+
+import java.security.Principal;
+import java.util.logging.Logger;
+
+import javax.security.auth.Subject;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.security.SecurityToken;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.security.SecurityContext;
+
+public abstract class AbstractSecurityContextInInterceptor extends AbstractPhaseInterceptor<Message> {
+
+ private static final Logger LOG =
+ LogUtils.getL7dLogger(AbstractSecurityContextInInterceptor.class);
+
+ public AbstractSecurityContextInInterceptor() {
+ super(Phase.PRE_INVOKE);
+ }
+
+ public void handleMessage(Message message) throws Fault {
+ SecurityToken token = message.get(SecurityToken.class);
+ if (token == null) {
+ reportSecurityException("Security Token is not available on the current message");
+ }
+
+ SecurityContext context = message.get(SecurityContext.class);
+ if (context == null || context.getUserPrincipal() == null) {
+ reportSecurityException("User Principal is not available on the current message");
+ }
+
+ Subject subject = null;
+ try {
+ subject = createSubject(token);
+ } catch (Exception ex) {
+ reportSecurityException("Failed Authentication : Subject has not been created, "
+ + ex.getMessage());
+ }
+ if (subject == null || subject.getPrincipals().size() == 0) {
+ reportSecurityException("Failed Authentication : Invalid Subject");
+ }
+
+ SecurityContext sc = createSecurityContext(context.getUserPrincipal(), subject);
+ message.put(SecurityContext.class, sc);
+ }
+
+ protected SecurityContext createSecurityContext(Principal p, Subject subject) {
+ return new DefaultSecurityContext(p, subject);
+ }
+
+ protected abstract Subject createSubject(SecurityToken token);
+
+ protected void reportSecurityException(String errorMessage) {
+ LOG.severe(errorMessage);
+ throw new SecurityException(errorMessage);
+ }
+}
Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractSecurityContextInInterceptor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractSecurityContextInInterceptor.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractUsernameTokenInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractUsernameTokenInInterceptor.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractUsernameTokenInInterceptor.java (added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractUsernameTokenInInterceptor.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,40 @@
+/**
+ * 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.interceptor.security;
+
+import javax.security.auth.Subject;
+
+import org.apache.cxf.common.security.SecurityToken;
+import org.apache.cxf.common.security.TokenType;
+import org.apache.cxf.common.security.UsernameToken;
+
+public abstract class AbstractUsernameTokenInInterceptor extends AbstractSecurityContextInInterceptor {
+
+ protected Subject createSubject(SecurityToken token) {
+ if (token.getTokenType() != TokenType.UsernameToken) {
+ reportSecurityException("Unsupported token type " + token.getTokenType().toString());
+ }
+ UsernameToken ut = (UsernameToken)token;
+ return createSubject(ut);
+ }
+
+ protected abstract Subject createSubject(UsernameToken token);
+
+
+}
Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractUsernameTokenInInterceptor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/AbstractUsernameTokenInInterceptor.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java (added)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,76 @@
+/**
+ * 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.interceptor.security;
+
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.Enumeration;
+
+import javax.security.auth.Subject;
+
+import org.apache.cxf.security.SecurityContext;
+
+/**
+ * SecurityContext which implements isUserInRole using the
+ * following approach : skip the first Subject principal, and then checks
+ * Groups the principal is a member of
+ *
+ * TODO : consider moving this class into common/security
+ */
+public class DefaultSecurityContext implements SecurityContext {
+
+ private Principal p;
+ private Subject subject;
+
+ public DefaultSecurityContext(Principal p, Subject subject) {
+ this.p = p;
+ this.subject = subject;
+ }
+
+ public Principal getUserPrincipal() {
+ return p;
+ }
+ public boolean isUserInRole(String role) {
+ if (subject == null || subject.getPrincipals().size() <= 1) {
+ return false;
+ }
+ for (Principal principal : subject.getPrincipals()) {
+ if (principal instanceof Group && checkGroup((Group)principal, role)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected boolean checkGroup(Group group, String role) {
+ if (group.getName().equals(role)) {
+ return true;
+ }
+
+ for (Enumeration<? extends Principal> members = group.members(); members.hasMoreElements();) {
+ // this might be a plain role but could represent a group consisting of other groups/roles
+ Principal member = members.nextElement();
+ if (member.getName().equals(role)
+ || member instanceof Group && checkGroup((Group)member, role)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/security/DefaultSecurityContext.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java (added)
+++ cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,75 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.interceptor.security;
+
+import java.security.Principal;
+import java.security.acl.Group;
+
+import javax.security.auth.Subject;
+
+import org.apache.cxf.common.security.SimpleGroup;
+import org.apache.cxf.common.security.SimplePrincipal;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class DefaultSecurityContextTest extends Assert {
+
+ @Test
+ public void testUserNotInRole() {
+ Subject s = new Subject();
+ Principal p = new SimplePrincipal("Barry");
+ s.getPrincipals().add(p);
+ assertFalse(new DefaultSecurityContext(p, s).isUserInRole("friend"));
+ }
+
+ @Test
+ public void testUserInRole() {
+ Subject s = new Subject();
+ Principal p = new SimplePrincipal("Barry");
+ s.getPrincipals().add(p);
+ s.getPrincipals().add(new SimpleGroup("friend", p));
+ assertTrue(new DefaultSecurityContext(p, s).isUserInRole("friend"));
+ }
+
+ @Test
+ public void testUserInRole2() {
+ Subject s = new Subject();
+ Principal p = new SimplePrincipal("Barry");
+ s.getPrincipals().add(p);
+ Group group = new SimpleGroup("Roles", p);
+ group.addMember(new SimpleGroup("friend"));
+ s.getPrincipals().add(group);
+ assertTrue(new DefaultSecurityContext(p, s).isUserInRole("friend"));
+ }
+
+ @Test
+ public void testUserInRole3() {
+ Subject s = new Subject();
+ Principal p = new SimplePrincipal("Barry");
+ s.getPrincipals().add(p);
+ Group group = new SimpleGroup("Roles", p);
+ Group subgroup = new SimpleGroup("subgroup");
+ subgroup.addMember(new SimpleGroup("friend"));
+ group.addMember(subgroup);
+ s.getPrincipals().add(group);
+ assertTrue(new DefaultSecurityContext(p, s).isUserInRole("friend"));
+ }
+
+}
Propchange: cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/core/src/test/java/org/apache/cxf/interceptor/security/DefaultSecurityContextTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java Thu Oct 14 16:22:13 2010
@@ -31,6 +31,7 @@ public final class SecurityConstants {
public static final String USERNAME = "ws-security.username";
public static final String PASSWORD = "ws-security.password";
public static final String VALIDATE_PASSWORD = "ws-security.validate.password";
+ public static final String USERNAME_TOKEN_NO_CALLBACKS = "ws-security.ut.no-callbacks";
public static final String CALLBACK_HANDLER = "ws-security.callback-handler";
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractUsernameTokenAuthenticatingInterceptor.java Thu Oct 14 16:22:13 2010
@@ -22,33 +22,24 @@ import java.io.IOException;
import java.security.Principal;
import java.util.HashMap;
import java.util.Map;
-import java.util.Vector;
-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.UnsupportedCallbackException;
import javax.xml.namespace.QName;
-import org.w3c.dom.Element;
-
import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.interceptor.security.DefaultSecurityContext;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.PhaseInterceptorChain;
import org.apache.cxf.security.SecurityContext;
import org.apache.ws.security.WSConstants;
-import org.apache.ws.security.WSDocInfo;
import org.apache.ws.security.WSPasswordCallback;
-import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.WSSecurityEngine;
-import org.apache.ws.security.WSSecurityEngineResult;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.WSUsernameTokenPrincipal;
-import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.handler.RequestData;
-import org.apache.ws.security.message.token.UsernameToken;
import org.apache.ws.security.processor.Processor;
@@ -69,8 +60,7 @@ import org.apache.ws.security.processor.
* an application is expected to provide a password callback handler for decrypting the token only.
*
*/
-public abstract class AbstractUsernameTokenAuthenticatingInterceptor extends WSS4JInInterceptor
- implements Processor {
+public abstract class AbstractUsernameTokenAuthenticatingInterceptor extends WSS4JInInterceptor {
private static final Logger LOG =
LogUtils.getL7dLogger(AbstractUsernameTokenAuthenticatingInterceptor.class);
@@ -130,11 +120,15 @@ public abstract class AbstractUsernameTo
try {
subject = createSubject(name, password, isDigest, nonce, created);
} catch (Exception ex) {
- throw new WSSecurityException("Failed Authentication : Subject has not been created", ex);
+ String errorMessage = "Failed Authentication : Subject has not been created";
+ LOG.severe(errorMessage);
+ throw new WSSecurityException(errorMessage, ex);
}
if (subject == null || subject.getPrincipals().size() == 0
|| !subject.getPrincipals().iterator().next().getName().equals(name)) {
- throw new WSSecurityException("Failed Authentication : Invalid Subject");
+ String errorMessage = "Failed Authentication : Invalid Subject";
+ LOG.severe(errorMessage);
+ throw new WSSecurityException(errorMessage);
}
msg.put(Subject.class, subject);
}
@@ -164,7 +158,7 @@ public abstract class AbstractUsernameTo
*
*/
@Override
- protected CallbackHandler getCallback(RequestData reqData, int doAction)
+ protected CallbackHandler getCallback(RequestData reqData, int doAction, boolean utNoCallbacks)
throws WSSecurityException {
// Given that a custom UT processor is used for dealing with digests
@@ -174,63 +168,46 @@ public abstract class AbstractUsernameTo
if ((doAction & WSConstants.UT) != 0) {
CallbackHandler pwdCallback = null;
try {
- pwdCallback = super.getCallback(reqData, doAction);
+ pwdCallback = super.getCallback(reqData, doAction, false);
} catch (Exception ex) {
// ignore
}
- return new DelegatingCallbackHandler(pwdCallback);
+ return new SubjectCreatingCallbackHandler(pwdCallback);
}
- return super.getCallback(reqData, doAction);
+ return super.getCallback(reqData, doAction, false);
}
@Override
- protected WSSecurityEngine getSecurityEngine() {
+ protected WSSecurityEngine getSecurityEngine(boolean utNoCallbacks) {
if (!supportDigestPasswords) {
- return super.getSecurityEngine();
+ return super.getSecurityEngine(false);
}
Map<QName, Object> profiles = new HashMap<QName, Object>(3);
- profiles.put(new QName(WSConstants.WSSE_NS, WSConstants.USERNAME_TOKEN_LN), this);
- profiles.put(new QName(WSConstants.WSSE11_NS, WSConstants.USERNAME_TOKEN_LN), this);
+
+ Processor processor = new CustomUsernameTokenProcessor();
+ profiles.put(new QName(WSConstants.WSSE_NS, WSConstants.USERNAME_TOKEN_LN), processor);
+ profiles.put(new QName(WSConstants.WSSE11_NS, WSConstants.USERNAME_TOKEN_LN), processor);
return createSecurityEngine(profiles);
}
- public void handleToken(Element elem,
- Crypto crypto,
- Crypto decCrypto,
- CallbackHandler cb,
- WSDocInfo wsDocInfo,
- Vector returnResults,
- WSSConfig config) throws WSSecurityException {
- new CustomUsernameTokenProcessor().handleToken(elem, crypto, decCrypto, cb, wsDocInfo,
- returnResults, config);
- }
-
-
- protected class DelegatingCallbackHandler implements CallbackHandler {
+ protected class SubjectCreatingCallbackHandler extends DelegatingCallbackHandler {
- private CallbackHandler pwdHandler;
-
- public DelegatingCallbackHandler(CallbackHandler pwdHandler) {
- this.pwdHandler = pwdHandler;
+ public SubjectCreatingCallbackHandler(CallbackHandler pwdHandler) {
+ super(pwdHandler);
}
- public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
- for (Callback c : callbacks) {
- if (c instanceof WSPasswordCallback) {
- WSPasswordCallback pc = (WSPasswordCallback)c;
- if (WSConstants.PASSWORD_TEXT.equals(pc.getPasswordType())
- && pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN) {
- AbstractUsernameTokenAuthenticatingInterceptor.this.setSubject(
- pc.getIdentifier(), pc.getPassword(), false, null, null);
- } else if (pwdHandler != null) {
- pwdHandler.handle(callbacks);
- }
- }
+ @Override
+ protected void handleCallback(Callback c) throws IOException {
+ if (c instanceof WSPasswordCallback) {
+ WSPasswordCallback pc = (WSPasswordCallback)c;
+ if (WSConstants.PASSWORD_TEXT.equals(pc.getPasswordType())
+ && pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN) {
+ AbstractUsernameTokenAuthenticatingInterceptor.this.setSubject(
+ pc.getIdentifier(), pc.getPassword(), false, null, null);
+ }
}
-
}
-
}
/**
@@ -239,56 +216,18 @@ public abstract class AbstractUsernameTo
* override its handleUsernameToken only.
*
*/
- private class CustomUsernameTokenProcessor implements Processor {
-
- private String utId;
- private UsernameToken ut;
+ protected class CustomUsernameTokenProcessor extends UsernameTokenProcessorWithoutCallbacks {
- @SuppressWarnings("unchecked")
- public void handleToken(Element elem, Crypto crypto, Crypto decCrypto, CallbackHandler cb,
- WSDocInfo wsDocInfo, Vector returnResults, WSSConfig wsc) throws WSSecurityException {
- if (LOG.isLoggable(Level.FINE)) {
- LOG.fine("Found UsernameToken list element");
- }
-
- Principal principal = handleUsernameToken((Element) elem, cb);
- returnResults.add(
- 0,
- new WSSecurityEngineResult(WSConstants.UT, principal, null, null, null)
- );
- utId = ut.getID();
- }
-
- private WSUsernameTokenPrincipal handleUsernameToken(
- Element token, CallbackHandler cb) throws WSSecurityException {
- //
- // Parse the UsernameToken element
- //
- ut = new UsernameToken(token, false);
- String user = ut.getName();
- String password = ut.getPassword();
- String nonce = ut.getNonce();
- String createdTime = ut.getCreated();
- String pwType = ut.getPasswordType();
- if (LOG.isLoggable(Level.FINE)) {
- LOG.fine("UsernameToken user " + user);
- LOG.fine("UsernameToken password " + password);
- }
-
+ @Override
+ protected WSUsernameTokenPrincipal createPrincipal(String user,
+ String password,
+ boolean isHashed,
+ String nonce,
+ String createdTime,
+ String pwType) throws WSSecurityException {
AbstractUsernameTokenAuthenticatingInterceptor.this.setSubject(
- user, password, ut.isHashed(), nonce, createdTime);
-
- WSUsernameTokenPrincipal principal = new WSUsernameTokenPrincipal(user, ut.isHashed());
- principal.setNonce(nonce);
- principal.setPassword(password);
- principal.setCreatedTime(createdTime);
- principal.setPasswordType(pwType);
-
- return principal;
- }
-
- public String getId() {
- return utId;
+ user, password, isHashed, nonce, createdTime);
+ return super.createPrincipal(user, password, isHashed, nonce, createdTime, pwType);
}
}
Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DelegatingCallbackHandler.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DelegatingCallbackHandler.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DelegatingCallbackHandler.java (added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DelegatingCallbackHandler.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,48 @@
+/**
+ * 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.wss4j;
+
+import java.io.IOException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+public class DelegatingCallbackHandler implements CallbackHandler {
+
+ private CallbackHandler pwdHandler;
+
+ public DelegatingCallbackHandler(CallbackHandler pwdHandler) {
+ this.pwdHandler = pwdHandler;
+ }
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ for (Callback c : callbacks) {
+ handleCallback(c);
+ }
+ if (pwdHandler != null) {
+ pwdHandler.handle(callbacks);
+ }
+ }
+
+ protected void handleCallback(Callback c) throws IOException {
+ // complete
+ }
+}
Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DelegatingCallbackHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/DelegatingCallbackHandler.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java Thu Oct 14 16:22:13 2010
@@ -455,7 +455,7 @@ public class PolicyBasedWSS4JInIntercept
}
protected void doResults(SoapMessage msg, String actor,
- SOAPMessage doc, Vector results)
+ SOAPMessage doc, Vector results, boolean utWithCallbacks)
throws SOAPException, XMLStreamException, WSSecurityException {
AssertionInfoMap aim = msg.get(AssertionInfoMap.class);
@@ -502,12 +502,15 @@ public class PolicyBasedWSS4JInIntercept
for (AssertionInfo ai : ais) {
ai.setAsserted(true);
}
- WSUsernameTokenPrincipal princ
- = (WSUsernameTokenPrincipal)wser.get(WSSecurityEngineResult.TAG_PRINCIPAL);
- for (AssertionInfo ai : ais) {
- UsernameToken tok = (UsernameToken)ai.getAssertion();
- if (tok.isHashPassword() != princ.isPasswordDigest()) {
- ai.setNotAsserted("Password hashing policy not enforced");
+
+ if (utWithCallbacks) {
+ WSUsernameTokenPrincipal princ
+ = (WSUsernameTokenPrincipal)wser.get(WSSecurityEngineResult.TAG_PRINCIPAL);
+ for (AssertionInfo ai : ais) {
+ UsernameToken tok = (UsernameToken)ai.getAssertion();
+ if (tok.isHashPassword() != princ.isPasswordDigest()) {
+ ai.setNotAsserted("Password hashing policy not enforced");
+ }
}
}
}
@@ -557,7 +560,7 @@ public class PolicyBasedWSS4JInIntercept
assertPolicy(aim, SP12Constants.SIGNED_ENDORSING_ENCRYPTED_SUPPORTING_TOKENS);
}
- super.doResults(msg, actor, doc, results);
+ super.doResults(msg, actor, doc, results, utWithCallbacks);
}
private void assertHeadersExists(AssertionInfoMap aim, SoapMessage msg, SOAPMessage doc)
throws SOAPException {
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenInterceptor.java Thu Oct 14 16:22:13 2010
@@ -45,6 +45,7 @@ import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.interceptor.security.DefaultSecurityContext;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.security.SecurityContext;
Added: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java (added)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,107 @@
+/**
+ * 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.wss4j;
+
+import java.security.Principal;
+import java.util.Vector;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDocInfo;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.WSUsernameTokenPrincipal;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.message.token.UsernameToken;
+import org.apache.ws.security.processor.Processor;
+
+
+/**
+ * UsernameToken processor which creates Principal
+ * without delegating to CallbackHandlers
+ */
+public class UsernameTokenProcessorWithoutCallbacks implements Processor {
+
+ private static final Logger LOG =
+ LogUtils.getL7dLogger(UsernameTokenProcessorWithoutCallbacks.class);
+
+ private String utId;
+ private UsernameToken ut;
+
+ @SuppressWarnings("unchecked")
+ public void handleToken(Element elem, Crypto crypto, Crypto decCrypto, CallbackHandler cb,
+ WSDocInfo wsDocInfo, Vector returnResults, WSSConfig wsc) throws WSSecurityException {
+ if (LOG.isLoggable(Level.FINE)) {
+ LOG.fine("Found UsernameToken list element");
+ }
+
+ Principal principal = handleUsernameToken((Element) elem, cb);
+ returnResults.add(
+ 0,
+ new WSSecurityEngineResult(WSConstants.UT, principal, null, null, null)
+ );
+ utId = ut.getID();
+ }
+
+ private WSUsernameTokenPrincipal handleUsernameToken(
+ Element token, CallbackHandler cb) throws WSSecurityException {
+ //
+ // Parse the UsernameToken element
+ //
+ ut = new UsernameToken(token, false);
+ String user = ut.getName();
+ String password = ut.getPassword();
+ String nonce = ut.getNonce();
+ String createdTime = ut.getCreated();
+ String pwType = ut.getPasswordType();
+ if (LOG.isLoggable(Level.FINE)) {
+ LOG.fine("UsernameToken user " + user);
+ LOG.fine("UsernameToken password " + password);
+ }
+
+ return createPrincipal(user, password, ut.isHashed(), nonce, createdTime, pwType);
+ }
+
+ protected WSUsernameTokenPrincipal createPrincipal(String user,
+ String password,
+ boolean isHashed,
+ String nonce,
+ String createdTime,
+ String pwType) throws WSSecurityException {
+ WSUsernameTokenPrincipal principal = new WSUsernameTokenPrincipal(user, isHashed);
+ principal.setNonce(nonce);
+ principal.setPassword(password);
+ principal.setCreatedTime(createdTime);
+ principal.setPasswordType(pwType);
+
+ return principal;
+ }
+
+ public String getId() {
+ return utId;
+ }
+}
Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/UsernameTokenProcessorWithoutCallbacks.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java (original)
+++ cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java Thu Oct 14 16:22:13 2010
@@ -21,6 +21,7 @@ package org.apache.cxf.ws.security.wss4j
import java.io.IOException;
import java.security.Principal;
import java.security.cert.X509Certificate;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
@@ -46,9 +47,11 @@ import org.apache.cxf.binding.soap.saaj.
import org.apache.cxf.common.classloader.ClassLoaderUtils;
import org.apache.cxf.common.i18n.Message;
import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.security.UsernameToken;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.security.SecurityContext;
import org.apache.cxf.staxutils.StaxUtils;
@@ -149,13 +152,17 @@ public class WSS4JInInterceptor extends
return;
}
msg.put(SECURITY_PROCESSED, Boolean.TRUE);
+
+ boolean utWithCallbacks =
+ !MessageUtils.getContextualBoolean(msg, SecurityConstants.USERNAME_TOKEN_NO_CALLBACKS, false);
+
WSSConfig config = (WSSConfig)msg.getContextualProperty(WSSConfig.class.getName());
WSSecurityEngine engine;
if (config != null) {
engine = new WSSecurityEngine();
engine.setWssConfig(config);
} else {
- engine = getSecurityEngine();
+ engine = getSecurityEngine(utWithCallbacks);
}
SOAPMessage doc = getSOAPMessage(msg);
@@ -192,7 +199,7 @@ public class WSS4JInInterceptor extends
String actor = (String)getOption(WSHandlerConstants.ACTOR);
- CallbackHandler cbHandler = getCallback(reqData, doAction);
+ CallbackHandler cbHandler = getCallback(reqData, doAction, utWithCallbacks);
/*
* Get and check the Signature specific parameters first because
@@ -225,7 +232,7 @@ public class WSS4JInInterceptor extends
checkSignatures(msg, reqData, wsResult);
checkTimestamps(msg, reqData, wsResult);
checkActions(msg, reqData, wsResult, actions);
- doResults(msg, actor, doc, wsResult);
+ doResults(msg, actor, doc, wsResult, utWithCallbacks);
} else { // no security header found
// Create an empty result vector to pass into the required validation
// methods.
@@ -360,8 +367,14 @@ public class WSS4JInInterceptor extends
protected void computeAction(SoapMessage msg, RequestData reqData) {
}
+
protected void doResults(SoapMessage msg, String actor, SOAPMessage doc, Vector wsResult)
throws SOAPException, XMLStreamException, WSSecurityException {
+ doResults(msg, actor, doc, wsResult, false);
+ }
+
+ protected void doResults(SoapMessage msg, String actor, SOAPMessage doc, Vector wsResult,
+ boolean utWithCallbacks) throws SOAPException, XMLStreamException, WSSecurityException {
/*
* All ok up to this point. Now construct and setup the security result
* structure. The service may fetch this and check it.
@@ -405,7 +418,18 @@ public class WSS4JInInterceptor extends
for (WSSecurityEngineResult o : CastUtils.cast(wsResult, WSSecurityEngineResult.class)) {
final Principal p = (Principal)o.get(WSSecurityEngineResult.TAG_PRINCIPAL);
if (p != null) {
- msg.put(PRINCIPAL_RESULT, p);
+ msg.put(PRINCIPAL_RESULT, p);
+ if (!utWithCallbacks && p instanceof WSUsernameTokenPrincipal) {
+ WSUsernameTokenPrincipal utp = (WSUsernameTokenPrincipal)p;
+ msg.put(org.apache.cxf.common.security.SecurityToken.class,
+ new UsernameToken(utp.getName(),
+ utp.getPassword(),
+ utp.getPasswordType(),
+ utp.isPasswordDigest(),
+ utp.getNonce(),
+ utp.getCreatedTime()));
+
+ }
SecurityContext sc = msg.get(SecurityContext.class);
if (sc == null || sc.getUserPrincipal() == null) {
msg.put(SecurityContext.class, createSecurityContext(p));
@@ -477,6 +501,21 @@ public class WSS4JInInterceptor extends
}
+ protected CallbackHandler getCallback(RequestData reqData, int doAction, boolean utWithCallbacks)
+ throws WSSecurityException {
+ if (!utWithCallbacks && (doAction & WSConstants.UT) != 0) {
+ CallbackHandler pwdCallback = null;
+ try {
+ pwdCallback = getCallback(reqData, doAction);
+ } catch (Exception ex) {
+ // ignore
+ }
+ return new DelegatingCallbackHandler(pwdCallback);
+ } else {
+ return getCallback(reqData, doAction);
+ }
+ }
+
protected CallbackHandler getCallback(RequestData reqData, int doAction) throws WSSecurityException {
/*
* To check a UsernameToken or to decrypt an encrypted message we need a
@@ -535,11 +574,19 @@ public class WSS4JInInterceptor extends
* TODO the WSHandler base class defines secEngine to be static, which
* is really bad, because the engine has mutable state on it.
*/
- protected WSSecurityEngine
- getSecurityEngine() {
+ protected WSSecurityEngine getSecurityEngine(boolean utWithCallbacks) {
if (secEngineOverride != null) {
return secEngineOverride;
}
+
+ if (!utWithCallbacks) {
+ Map<QName, Object> profiles = new HashMap<QName, Object>(3);
+ Processor processor = new UsernameTokenProcessorWithoutCallbacks();
+ profiles.put(new QName(WSConstants.WSSE_NS, WSConstants.USERNAME_TOKEN_LN), processor);
+ profiles.put(new QName(WSConstants.WSSE11_NS, WSConstants.USERNAME_TOKEN_LN), processor);
+ return createSecurityEngine(profiles);
+ }
+
return secEngine;
}
Modified: cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10Test.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10Test.java?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10Test.java (original)
+++ cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10Test.java Thu Oct 14 16:22:13 2010
@@ -28,9 +28,14 @@ import javax.xml.namespace.QName;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.systest.ws.wssec10.server.Server;
import org.apache.cxf.systest.ws.wssec11.WSSecurity11Common;
import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
+
import org.junit.BeforeClass;
import org.junit.Test;
@@ -95,7 +100,16 @@ public class WSSecurity10Test extends Ab
),
IPingService.class
);
+
+ Client cl = ClientProxy.getClient(port);
+ HTTPConduit http = (HTTPConduit) cl.getConduit();
+
+ HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
+ httpClientPolicy.setConnectionTimeout(0);
+ httpClientPolicy.setReceiveTimeout(0);
+
+ http.setClient(httpClientPolicy);
final String output = port.echo(INPUT);
assertEquals(INPUT, output);
}
Modified: cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10UsernameAuthorizationTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10UsernameAuthorizationTest.java?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10UsernameAuthorizationTest.java (original)
+++ cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/WSSecurity10UsernameAuthorizationTest.java Thu Oct 14 16:22:13 2010
@@ -28,8 +28,12 @@ import javax.xml.namespace.QName;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.endpoint.Client;
+import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.systest.ws.wssec10.server.AuthorizedServer;
import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.transport.http.HTTPConduit;
+import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -42,6 +46,7 @@ import wssec.wssec10.PingService;
*
*/
public class WSSecurity10UsernameAuthorizationTest extends AbstractBusClientServerTestBase {
+ static final String SSL_PORT = allocatePort(AuthorizedServer.class, 1);
static final String PORT = allocatePort(AuthorizedServer.class);
private static final String INPUT = "foo";
@@ -58,9 +63,9 @@ public class WSSecurity10UsernameAuthori
}
@Test
- public void testClientServerAuthorized() {
+ public void testClientServerUTOnlyAuthorized() {
- IPingService port = getPort(
+ IPingService port = getUTOnlyPort(
"org/apache/cxf/systest/ws/wssec10/client/client_restricted.xml", false);
final String output = port.echo(INPUT);
@@ -68,9 +73,9 @@ public class WSSecurity10UsernameAuthori
}
@Test
- public void testClientServerUnauthorized() {
+ public void testClientServerUTOnlyUnauthorized() {
- IPingService port = getPort(
+ IPingService port = getUTOnlyPort(
"org/apache/cxf/systest/ws/wssec10/client/client_restricted_unauthorized.xml", true);
try {
@@ -81,7 +86,48 @@ public class WSSecurity10UsernameAuthori
}
}
- private static IPingService getPort(String configName, boolean hashed) {
+ @Test
+ public void testClientServerComplexPolicyAuthorized() {
+
+ IPingService port = getComplexPolicyPort(
+ "org/apache/cxf/systest/ws/wssec10/client/client_restricted.xml");
+
+ final String output = port.echo(INPUT);
+ assertEquals(INPUT, output);
+ }
+
+ @Test
+ public void testClientServerComplexPolicyUnauthorized() {
+
+ IPingService port = getComplexPolicyPort(
+ "org/apache/cxf/systest/ws/wssec10/client/client_restricted_unauthorized.xml");
+
+ try {
+ port.echo(INPUT);
+ fail("Frank is unauthorized");
+ } catch (Exception ex) {
+ assertEquals("Unauthorized", ex.getMessage());
+ }
+ }
+
+ private static IPingService getComplexPolicyPort(String configName) {
+ Bus bus = new SpringBusFactory().createBus(configName);
+
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+ PingService svc = new PingService(getWsdlLocation("UserNameOverTransport"));
+ final IPingService port =
+ svc.getPort(
+ new QName(
+ "http://WSSec/wssec10",
+ "UserNameOverTransport" + "_IPingService"
+ ),
+ IPingService.class
+ );
+ return port;
+ }
+
+ private static IPingService getUTOnlyPort(String configName, boolean hashed) {
Bus bus = new SpringBusFactory().createBus(configName);
BusFactory.setDefaultBus(bus);
@@ -109,4 +155,19 @@ public class WSSecurity10UsernameAuthori
}
+ private static URL getWsdlLocation(String portPrefix) {
+ try {
+ if ("UserNameOverTransport".equals(portPrefix)) {
+ return new URL("https://localhost:" + SSL_PORT + "/" + portPrefix + "?wsdl");
+ } else if ("MutualCertificate10SignEncrypt".equals(portPrefix)) {
+ return new URL("http://localhost:" + PORT + "/" + portPrefix + "?wsdl");
+ } else if ("MutualCertificate10SignEncryptRsa15TripleDes".equals(portPrefix)) {
+ return new URL("http://localhost:" + PORT + "/" + portPrefix + "?wsdl");
+ }
+ } catch (MalformedURLException mue) {
+ return null;
+ }
+ return null;
+ }
+
}
Modified: cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/client/client_restricted_unauthorized.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/client/client_restricted_unauthorized.xml?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/client/client_restricted_unauthorized.xml (original)
+++ cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/client/client_restricted_unauthorized.xml Thu Oct 14 16:22:13 2010
@@ -47,4 +47,21 @@
</jaxws:properties>
</jaxws:client>
+ <jaxws:client name="{http://WSSec/wssec10}UserNameOverTransport_IPingService" createdFromAPI="true">
+ <jaxws:properties>
+ <entry key="ws-security.username" value="Frank"/>
+ <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.ws.wssec10.client.UTPasswordCallback"/>
+ </jaxws:properties>
+ </jaxws:client>
+
+ <http:conduit name="https://.*/UserNameOverTransport.*">
+ <http:tlsClientParameters disableCNCheck="true">
+ <sec:keyManagers keyPassword="password">
+ <sec:keyStore type="jks" password="password" resource="org/apache/cxf/systest/ws/wssec10/certs/restricted/alice.jks"/>
+ </sec:keyManagers>
+ <sec:trustManagers>
+ <sec:keyStore type="jks" password="password" resource="org/apache/cxf/systest/ws/wssec10/certs/restricted/bob.jks"/>
+ </sec:trustManagers>
+ </http:tlsClientParameters>
+ </http:conduit>
</beans>
Added: cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java?rev=1022599&view=auto
==============================================================================
--- cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java (added)
+++ cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java Thu Oct 14 16:22:13 2010
@@ -0,0 +1,56 @@
+/**
+ * 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.ws.wssec10.server;
+
+import javax.security.auth.Subject;
+
+import org.apache.cxf.common.security.SimpleGroup;
+import org.apache.cxf.common.security.SimplePrincipal;
+import org.apache.cxf.common.security.UsernameToken;
+import org.apache.cxf.interceptor.security.AbstractUsernameTokenInInterceptor;
+
+public class SimpleUsernameTokenInterceptor extends AbstractUsernameTokenInInterceptor {
+
+ protected Subject createSubject(UsernameToken ut) {
+ return createSubject(ut.getName(), ut.getPassword(), ut.isHashed(),
+ ut.getNonce(), ut.getCreatedTime());
+ }
+
+ protected Subject createSubject(String name,
+ String password,
+ boolean isDigest,
+ String nonce,
+ String created) throws SecurityException {
+ Subject subject = new Subject();
+
+ // delegate to the external security system if possible
+
+ // authenticate the user somehow
+ subject.getPrincipals().add(new SimplePrincipal(name));
+
+ // add roles this user is in
+ String roleName = "Alice".equals(name) ? "developers" : "pms";
+ subject.getPrincipals().add(new SimpleGroup(roleName, name));
+ subject.setReadOnly();
+ return subject;
+ }
+
+}
+
+
Propchange: cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/SimpleUsernameTokenInterceptor.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/server_restricted_authorized.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/server_restricted_authorized.xml?rev=1022599&r1=1022598&r2=1022599&view=diff
==============================================================================
--- cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/server_restricted_authorized.xml (original)
+++ cxf/trunk/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/wssec10/server/server_restricted_authorized.xml Thu Oct 14 16:22:13 2010
@@ -39,6 +39,34 @@
">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
+ <!-- -->
+ <!-- Any services listening on port 9001 must use the following -->
+ <!-- Transport Layer Security (TLS) settings -->
+ <!-- -->
+ <httpj:engine-factory id="tls-settings">
+ <httpj:engine port="${testutil.ports.AuthorizedServer.1}">
+ <httpj:tlsServerParameters>
+ <sec:keyManagers keyPassword="password">
+ <sec:keyStore type="jks" password="password" resource="org/apache/cxf/systest/ws/wssec10/certs/restricted/bob.jks"/>
+ </sec:keyManagers>
+ <sec:trustManagers>
+ <sec:keyStore type="jks" password="password" resource="org/apache/cxf/systest/ws/wssec10/certs/restricted/alice.jks"/>
+ </sec:trustManagers>
+
+ <!--
+ <sec:cipherSuitesFilter>
+ <sec:include>.*_EXPORT_.*</sec:include>
+ <sec:include>.*_EXPORT1024_.*</sec:include>
+ <sec:include>.*_WITH_DES_.*</sec:include>
+ <sec:include>.*_WITH_NULL_.*</sec:include>
+ <sec:exclude>.*_DH_anon_.*</sec:exclude>
+ </sec:cipherSuitesFilter>
+ <sec:clientAuthentication want="true" required="true"/>
+ -->
+ </httpj:tlsServerParameters>
+ </httpj:engine>
+ </httpj:engine-factory>
+
<cxf:bus>
<cxf:features>
<p:policies/>
@@ -53,7 +81,7 @@
<bean id="customUTInterceptor" class="org.apache.cxf.systest.ws.wssec10.server.CustomUsernameTokenInterceptor"/>
-
+ <bean id="simpleUTInterceptor" class="org.apache.cxf.systest.ws.wssec10.server.SimpleUsernameTokenInterceptor"/>
<bean id="authorizationInterceptor" class="org.apache.cxf.interceptor.security.SimpleAuthorizingInterceptor">
<property name="methodRolesMap">
<map>
@@ -90,4 +118,30 @@
</jaxws:endpoint>
+ <!-- -->
+ <!-- Scenario 3.1 -->
+ <!-- -->
+ <jaxws:endpoint
+ id="UserNameOverTransport"
+ address="https://localhost:${testutil.ports.AuthorizedServer.1}/UserNameOverTransport"
+ serviceName="interop:PingService"
+ endpointName="interop:UserNameOverTransport_IPingService"
+ implementor="org.apache.cxf.systest.ws.wssec10.server.UserNameOverTransportRestricted"
+ depends-on="tls-settings">
+
+ <jaxws:properties>
+ <entry key="ws-security.username" value="Alice"/>
+ <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.ws.wssec10.server.UTPasswordCallback"/>
+
+ <!-- new property -->
+ <entry key="ws-security.ut.no-callbacks" value="true"/>
+ </jaxws:properties>
+
+ <jaxws:inInterceptors>
+ <ref bean="simpleUTInterceptor"/>
+ <ref bean="authorizationInterceptor"/>
+ </jaxws:inInterceptors>
+
+ </jaxws:endpoint>
+
</beans>