/** * Licensed 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.aurora.scheduler.http.api.security; import java.util.Optional; import javax.inject.Singleton; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; import com.google.common.annotations.VisibleForTesting; import com.google.inject.AbstractModule; import com.google.inject.Provides; import org.apache.aurora.scheduler.config.CliOptions; import org.apache.shiro.authc.credential.CredentialsMatcher; import org.apache.shiro.authc.credential.SimpleCredentialsMatcher; import org.apache.shiro.config.Ini; import org.apache.shiro.realm.text.IniRealm; /** * Provides an implementation of a Shiro {@link IniRealm} that uses a flat shiro.ini file for * authentication and authorization. Should be used in conjunction with the * {@link org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter} or other filter that * produces {@link org.apache.shiro.authc.UsernamePasswordToken}s. * * <p> * Another filter may still be used for authentication, in which case the ini file can still be * used to provide authorization configuration and the passwords will be ignored. */ public class IniShiroRealmModule extends AbstractModule { @Parameters(separators = "=") public static class Options { @Parameter(names = "-shiro_ini_path", description = "Path to shiro.ini for authentication and authorization configuration.", converter = ShiroIniConverter.class) public Ini shiroIniPath; @Parameter(names = "-shiro_credentials_matcher", description = "The shiro credentials matcher to use (will be constructed by Guice).") public Class<? extends CredentialsMatcher> shiroCredentialsMatcher = SimpleCredentialsMatcher.class; } private final Optional<Ini> ini; private final Optional<Class<? extends CredentialsMatcher>> shiroCredentialsMatcher; public IniShiroRealmModule(CliOptions options) { this( Optional.ofNullable(options.iniShiroRealm.shiroIniPath), Optional.ofNullable(options.iniShiroRealm.shiroCredentialsMatcher)); } @VisibleForTesting IniShiroRealmModule(Ini ini, Class<? extends CredentialsMatcher> shiroCredentialsMatcher) { this(Optional.of(ini), Optional.of(shiroCredentialsMatcher)); } private IniShiroRealmModule(Optional<Ini> ini, Optional<Class<? extends CredentialsMatcher>> shiroCredentialsMatcher) { this.ini = ini; this.shiroCredentialsMatcher = shiroCredentialsMatcher; } @Override protected void configure() { if (ini.isPresent()) { bind(Ini.class).toInstance(ini.get()); } else { addError("shiro.ini is required."); } if (shiroCredentialsMatcher.isPresent()) { bind(CredentialsMatcher.class).to(shiroCredentialsMatcher.get()).in(Singleton.class); } else { addError("shiro_credentials_matcher is required."); } ShiroUtils.addRealmBinding(binder()).to(IniRealm.class); } @Singleton @Provides public IniRealm providesIniReal(Ini providedIni, CredentialsMatcher providedShiroCredentialsMatcher) { IniRealm result = new IniRealm(providedIni); result.setCredentialsMatcher(providedShiroCredentialsMatcher); result.init(); return result; } }