Repository: cxf Updated Branches: refs/heads/3.1.x-fixes 842880b35 -> b9c24f41c
[CXF-6903]add a NameDigestPasswordCallbackHandler for JAASLoginInterceptor (cherry picked from commit 76a22608d19c94a578d96d383f9794cebf758520) Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/b9c24f41 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/b9c24f41 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/b9c24f41 Branch: refs/heads/3.1.x-fixes Commit: b9c24f41cb1cc7e4d572fa222ae5aa4f5f804ccb Parents: 842880b Author: Freeman Fang <[email protected]> Authored: Tue May 17 14:44:15 2016 +0800 Committer: Freeman Fang <[email protected]> Committed: Tue May 17 14:44:51 2016 +0800 ---------------------------------------------------------------------- .../NameDigestPasswordCallbackHandler.java | 122 +++++++++++++++++++ .../CallbackHandlerProviderUsernameToken.java | 10 +- 2 files changed, 131 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/b9c24f41/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; + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/b9c24f41/core/src/main/java/org/apache/cxf/interceptor/security/callback/CallbackHandlerProviderUsernameToken.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/interceptor/security/callback/CallbackHandlerProviderUsernameToken.java b/core/src/main/java/org/apache/cxf/interceptor/security/callback/CallbackHandlerProviderUsernameToken.java index 0534c83..7e6e284 100644 --- a/core/src/main/java/org/apache/cxf/interceptor/security/callback/CallbackHandlerProviderUsernameToken.java +++ b/core/src/main/java/org/apache/cxf/interceptor/security/callback/CallbackHandlerProviderUsernameToken.java @@ -22,6 +22,7 @@ import javax.security.auth.callback.CallbackHandler; import org.apache.cxf.common.security.SecurityToken; import org.apache.cxf.common.security.UsernameToken; +import org.apache.cxf.interceptor.security.NameDigestPasswordCallbackHandler; import org.apache.cxf.interceptor.security.NamePasswordCallbackHandler; import org.apache.cxf.message.Message; @@ -34,7 +35,14 @@ public class CallbackHandlerProviderUsernameToken implements CallbackHandlerProv return null; } UsernameToken ut = (UsernameToken)token; - return new NamePasswordCallbackHandler(ut.getName(), ut.getPassword()); + if (ut.getPasswordType().endsWith("PasswordDigest")) { + return new NameDigestPasswordCallbackHandler(ut.getName(), + ut.getPassword(), + ut.getNonce(), + ut.getCreatedTime()); + } else { + return new NamePasswordCallbackHandler(ut.getName(), ut.getPassword()); + } } }
