You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by ff...@apache.org on 2016/05/17 06:10:32 UTC
cxf git commit: [CXF-6903]add a NameDigestPasswordCallbackHandler for
JAASLoginInterceptor
Repository: cxf
Updated Branches:
refs/heads/3.0.x-fixes fe97922c9 -> 0a90b65a2
[CXF-6903]add a NameDigestPasswordCallbackHandler for JAASLoginInterceptor
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/0a90b65a
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/0a90b65a
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/0a90b65a
Branch: refs/heads/3.0.x-fixes
Commit: 0a90b65a2774694da7c738b08ab5fe253fb91a70
Parents: fe97922
Author: Freeman Fang <fr...@gmail.com>
Authored: Tue May 17 14:10:17 2016 +0800
Committer: Freeman Fang <fr...@gmail.com>
Committed: Tue May 17 14:10:17 2016 +0800
----------------------------------------------------------------------
.../security/JAASLoginInterceptor.java | 16 ++-
.../NameDigestPasswordCallbackHandler.java | 122 +++++++++++++++++++
2 files changed, 135 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/0a90b65a/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java b/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java
index a48ead9..7c0549a 100644
--- a/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java
+++ b/core/src/main/java/org/apache/cxf/interceptor/security/JAASLoginInterceptor.java
@@ -113,6 +113,8 @@ public class JAASLoginInterceptor extends AbstractPhaseInterceptor<Message> {
String name = null;
String password = null;
+ String nonce = null;
+ String createdTime = null;
AuthorizationPolicy policy = message.get(AuthorizationPolicy.class);
if (policy != null) {
@@ -125,6 +127,10 @@ public class JAASLoginInterceptor extends AbstractPhaseInterceptor<Message> {
UsernameToken ut = (UsernameToken)token;
name = ut.getName();
password = ut.getPassword();
+ if (ut.getPasswordType().endsWith("PasswordDigest")) {
+ nonce = ut.getNonce();
+ createdTime = ut.getCreatedTime();
+ }
}
}
@@ -133,7 +139,7 @@ public class JAASLoginInterceptor extends AbstractPhaseInterceptor<Message> {
}
try {
- CallbackHandler handler = getCallbackHandler(name, password);
+ CallbackHandler handler = getCallbackHandler(name, password, nonce, createdTime);
LoginContext ctx = new LoginContext(getContextName(), null, handler, loginConfig);
ctx.login();
@@ -168,8 +174,12 @@ public class JAASLoginInterceptor extends AbstractPhaseInterceptor<Message> {
}
}
- protected CallbackHandler getCallbackHandler(String name, String password) {
- return new NamePasswordCallbackHandler(name, password);
+ protected CallbackHandler getCallbackHandler(String name, String password, String nonce, String createdTime) {
+ if (nonce != null && createdTime != null) {
+ return new NameDigestPasswordCallbackHandler(name, password, nonce, createdTime);
+ } else {
+ return new NamePasswordCallbackHandler(name, password);
+ }
}
protected SecurityContext createSecurityContext(String name, Subject subject) {
http://git-wip-us.apache.org/repos/asf/cxf/blob/0a90b65a/core/src/main/java/org/apache/cxf/interceptor/security/NameDigestPasswordCallbackHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/cxf/interceptor/security/NameDigestPasswordCallbackHandler.java b/core/src/main/java/org/apache/cxf/interceptor/security/NameDigestPasswordCallbackHandler.java
new file mode 100644
index 0000000..8b61574
--- /dev/null
+++ b/core/src/main/java/org/apache/cxf/interceptor/security/NameDigestPasswordCallbackHandler.java
@@ -0,0 +1,122 @@
+/**
+ * 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.io.IOException;
+import java.lang.reflect.Method;
+import java.util.ResourceBundle;
+import java.util.logging.Logger;
+
+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 org.apache.cxf.common.i18n.BundleUtils;
+import org.apache.cxf.common.logging.LogUtils;
+
+public class NameDigestPasswordCallbackHandler implements CallbackHandler {
+
+ private static final ResourceBundle BUNDLE = BundleUtils.getBundle(NameDigestPasswordCallbackHandler.class);
+ private static final Logger LOG = LogUtils.getL7dLogger(NameDigestPasswordCallbackHandler.class);
+ private static final String PASSWORD_CALLBACK_NAME = "setObject";
+ private static final Class<?>[] PASSWORD_CALLBACK_TYPES =
+ new Class[]{Object.class, char[].class, String.class};
+
+ private String username;
+ private String password;
+ private String nonce;
+ private String createdTime;
+
+ private String passwordCallbackName;
+
+ public NameDigestPasswordCallbackHandler(String username, String password, String nonce, String createdTime) {
+ this(username, password, nonce, createdTime, null);
+ }
+
+ public NameDigestPasswordCallbackHandler(String username,
+ String password,
+ String nonce,
+ String createdTime,
+ String passwordCallbackName) {
+ this.username = username;
+ this.password = password;
+ this.nonce = nonce;
+ this.createdTime = createdTime;
+ this.passwordCallbackName = passwordCallbackName;
+ }
+
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ for (int i = 0; i < callbacks.length; i++) {
+ Callback callback = callbacks[i];
+ if (handleCallback(callback)) {
+ continue;
+ } else if (callback instanceof NameCallback) {
+ ((NameCallback) callback).setName(username);
+ } else if (callback instanceof PasswordCallback) {
+ PasswordCallback pwCallback = (PasswordCallback) callback;
+ pwCallback.setPassword(password.toCharArray());
+ } else if (!invokePasswordCallback(callback)) {
+ org.apache.cxf.common.i18n.Message errorMsg =
+ new org.apache.cxf.common.i18n.Message("UNSUPPORTED_CALLBACK_TYPE",
+ BUNDLE,
+ callbacks[i].getClass().getName());
+ LOG.info(errorMsg.toString());
+ throw new UnsupportedCallbackException(callbacks[i], errorMsg.toString());
+ }
+ }
+ }
+
+ protected boolean handleCallback(Callback callback) {
+ return false;
+ }
+
+ /*
+ * This method is called from the handle(Callback[]) method when the specified callback
+ * did not match any of the known callback classes. It looks for the callback method
+ * having the specified method name with one of the suppported parameter types.
+ * If found, it invokes the callback method on the object and returns true.
+ * If not, it returns false.
+ */
+ private boolean invokePasswordCallback(Callback callback) {
+ String cbname = passwordCallbackName == null
+ ? PASSWORD_CALLBACK_NAME : passwordCallbackName;
+ for (Class<?> arg : PASSWORD_CALLBACK_TYPES) {
+ try {
+ Method method = callback.getClass().getMethod(cbname, arg);
+ method.invoke(callback, arg == String.class ? password : password.toCharArray());
+ return true;
+ } catch (Exception e) {
+ // ignore and continue
+ LOG.fine(e.toString());
+ }
+ }
+ return false;
+ }
+
+ public String getNonce() {
+ return this.nonce;
+ }
+
+ public String getCreatedTime() {
+ return this.createdTime;
+ }
+
+}