| /* |
| * 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.sling.jcr.jackrabbit.base.security; |
| |
| |
| import org.apache.jackrabbit.core.config.BeanConfig; |
| import org.apache.jackrabbit.core.config.ConfigurationException; |
| import org.apache.jackrabbit.core.config.LoginModuleConfig; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import javax.security.auth.Subject; |
| import javax.security.auth.callback.CallbackHandler; |
| import javax.security.auth.login.Configuration; |
| import javax.security.auth.login.LoginContext; |
| import javax.security.auth.login.LoginException; |
| import javax.security.auth.spi.LoginModule; |
| import java.security.NoSuchAlgorithmException; |
| import java.security.NoSuchProviderException; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| public class DelegatingLoginModule implements LoginModule { |
| private static Logger logger = LoggerFactory.getLogger(DelegatingLoginModule.class); |
| public static final String JAAS_CONFIG_ALGO_NAME = "JavaLoginConfig"; |
| private LoginModule delegate; |
| private LoginContext loginContext; |
| private boolean loginSucceeded; |
| |
| private String appName; |
| private String delegateLoginModuleClass; |
| private String providerName; |
| |
| private LoginException loginException; |
| |
| |
| public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, |
| Map<String, ?> options) { |
| Configuration config = null; |
| try{ |
| config = Configuration.getInstance(JAAS_CONFIG_ALGO_NAME, null, providerName); |
| }catch (NoSuchProviderException e){ |
| logger.debug("No provider "+providerName+"found so far",e); |
| } catch (NoSuchAlgorithmException e) { |
| logger.debug("No provider "+providerName+"found so far for fetching JAAS " + |
| "config with algorithm name "+JAAS_CONFIG_ALGO_NAME,e); |
| } |
| |
| if(config != null){ |
| final Thread current = Thread.currentThread(); |
| final ClassLoader orig = current.getContextClassLoader(); |
| try { |
| current.setContextClassLoader(DelegatingLoginModule.class.getClassLoader()); |
| loginContext = new LoginContext(appName, subject,callbackHandler, config); |
| } catch (LoginException e) { |
| loginException = e; |
| } finally{ |
| current.setContextClassLoader(orig); |
| } |
| }else{ |
| //No support so far from OSGi so would use default logic used by Jackrabbit |
| //to construct the LoginModule |
| Properties p = new Properties(); |
| p.putAll(options); |
| BeanConfig bc = new BeanConfig(delegateLoginModuleClass,p); |
| LoginModuleConfig lmc = new LoginModuleConfig(bc); |
| try { |
| delegate = lmc.getLoginModule(); |
| delegate.initialize(subject,callbackHandler,sharedState,options); |
| logger.info("No JAAS Configuration provider found would be directly invoking LoginModule {}",delegateLoginModuleClass); |
| } catch (ConfigurationException e) { |
| //Behaviour is same as org.apache.jackrabbit.core.security.authentication.LocalAuthContext.login() |
| loginException = new LoginException(e.getMessage()); |
| } |
| } |
| } |
| |
| public boolean login() throws LoginException { |
| assertState(); |
| |
| if (loginContext == null) { |
| return delegate.login(); |
| } else { |
| loginContext.login(); |
| loginSucceeded = true; |
| return true; |
| } |
| } |
| |
| public boolean commit() throws LoginException { |
| assertState(); |
| |
| if (loginContext == null) { |
| return delegate.commit(); |
| } else { |
| return loginSucceeded; |
| } |
| } |
| |
| public boolean abort() throws LoginException { |
| assertState(); |
| |
| if (loginContext == null) { |
| return delegate.abort(); |
| } else { |
| return loginSucceeded; |
| } |
| } |
| |
| public boolean logout() throws LoginException { |
| assertState(); |
| |
| if (loginContext == null) { |
| return delegate.logout(); |
| } else { |
| loginContext.logout(); |
| return true; |
| } |
| } |
| |
| private void assertState() throws LoginException { |
| if(loginException != null){ |
| throw loginException; |
| } |
| } |
| |
| public void setAppName(String appName) { |
| this.appName = appName; |
| } |
| |
| public void setDelegateLoginModuleClass(String delegateLoginModuleClass) { |
| this.delegateLoginModuleClass = delegateLoginModuleClass; |
| } |
| |
| public void setProviderName(String providerName) { |
| this.providerName = providerName; |
| } |
| |
| } |