Integrating Jsecurity with Guice
--------------------------------
Key: JSEC-18
URL: https://issues.apache.org/jira/browse/JSEC-18
Project: JSecurity
Issue Type: New Feature
Reporter: Animesh Jain
Priority: Minor
/*
* 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 com.akube.framework.jsecurity.filter;
import com.google.inject.Injector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jsecurity.JSecurityException;
import org.jsecurity.SecurityUtils;
import org.jsecurity.mgt.SecurityManager;
import org.jsecurity.web.config.IniWebConfiguration;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
/**
* <p>JSecurity configuration that relies on Guice to define and initialize the JSecurity
SecurityManager
* instance (and all of its dependencies) and makes it avaialble to this filter by performing
a Guice injection.
* The URL/filter behavior is still loaded according to the behavior of the parent class
* {@link org.jsecurity.web.config.IniWebConfiguration}
* <p/>
*
* <p>
* The web.xml will need an entry like the following
*
*
<filter>
<filter-name>JSecurityFilter</filter-name>
<filter-class>org.jsecurity.guice.GuiceJSecurityFilter</filter-class>
<init-param>
<param-name>config</param-name>
<param-value>
</param-value>
</init-param>
<init-param>
<param-name>InjectorFactoryClass</param-name>
<param-value>app.bootstrap.guice.InjectorFactory</param-value>
</init-param>
<init-param>
<param-name>InjectorFactoryMethod</param-name>
<param-value>getInjector</param-value>
</init-param>
</filter>
the injector factory class - > injector factory method is called to obtain a guice injector
* </p>
*
* @author Animesh Jain
* @see IniWebConfiguration
* @since 0.9
*/
public class GuiceWebConfiguration extends IniWebConfiguration {
public static final String INJECTOR_FACTORY_CLASS = "InjectorFactoryClass";
public static final String INJECTOR_FACTORY_METHOD = "InjectorFactoryMethod";
private static final Log log = LogFactory.getLog(GuiceWebConfiguration.class);
protected Injector injector;
public Injector getInjector() {
return injector;
}
public void setInjector(Injector injector) {
this.injector = injector;
}
public GuiceWebConfiguration() {
}
@Override
public void init() throws JSecurityException {
String className = getFilterConfig().getInitParameter(INJECTOR_FACTORY_CLASS);
String methodName = getFilterConfig().getInitParameter(INJECTOR_FACTORY_METHOD);
System.out.println("*************** GuiceWebConfiguration init() ***************");
System.out.println("injector class = "+className);
System.out.println("injector method = "+methodName);
/*
Get injector from a class which holds an instance for this application. I had a static
method in a class that returns the injector.
I've put the class name and method name in filter init params.
*/
try {
Class clazz = Class.forName(className);
Method method = clazz.getMethod(methodName);
Injector injector = (Injector) method.invoke(null);
System.out.println("Injector instantiated = "+injector);
setInjector(injector);
} catch (ClassNotFoundException e) {
log.error("Injector factory class not found - "+className, e);
throw new JSecurityException("Injector factory class not found - "+className, e);
} catch (NoSuchMethodException e) {
log.error("Injector factory method not found - "+methodName+" in class "+className,
e);
throw new JSecurityException("Injector factory method not found - "+methodName+" in
class "+className, e);
} catch (InvocationTargetException e) {
log.error("InvocationTargetException when trying to invoke - "+methodName+" in class
"+className, e);
throw new JSecurityException("InvocationTargetException when trying to invoke - "+methodName+"
in class "+className, e);
} catch (IllegalAccessException e) {
log.error("IllegalAccessException when trying to invoke - "+methodName+" in class "+className,
e);
throw new JSecurityException("IllegalAccessException when trying to invoke - "+methodName+"
in class "+className, e);
}
super.init();
}
@Override
protected SecurityManager createDefaultSecurityManager() {
return createSecurityManager(null);
}
@Override
protected SecurityManager createSecurityManager(Map<String, Map<String, String>>
sections) {
return getOrCreateSecurityManager(injector, sections);
}
protected SecurityManager getOrCreateSecurityManager(Injector injector, Map<String, Map<String,
String>> sections) {
System.out.println("Trying to create Security Manager");
SecurityManager securityManager = null;
if (injector != null) {
/*
The security manager is obtained using the Guice injector.
Typically one will have to use a custom provider and bind it to the DefaultWebSecurityManager
class
This is the way Guice handles external configuration
*/
securityManager = injector.getInstance(DefaultWebSecurityManagerProvider.class).get();
SecurityUtils.setSecurityManager(securityManager);
} else {
throw new JSecurityException("Injector is null. Cannot instantiate security manager");
}
return securityManager;
}
}
----------------------------------------------------------------------------------------------------------------------------
The filter class can be -
/**
* <p>Extension of JSecurityFilter that uses {@link GuiceWebConfiguration} to configure
the JSecurity instance.</p>
*
* @author Animesh Jain
*/
public class GuiceJSecurityFilter extends JSecurityFilter {
public GuiceJSecurityFilter() {
this.configClassName = GuiceWebConfiguration.class.getName();
}
}
----------------------------------------------------------------------------------------------------------------------------
The Guice module can be
public class JSecurityModule extends AbstractModule {
protected void configure() {
// the DefaultWebSecurityManagerProvider class provides a custom configured SecurityManager
if needed
bind(DefaultWebSecurityManagerProvider.class).asEagerSingleton();
bindInterceptor(any(), annotatedWith(RequiresRoles.class), new AopAllianceAnnotationsAuthorizingMethodInterceptor());
}
}
----------------------------------------------------------------------------------------------------------------------------
In my own project I've somewhat tried to abstract out a few classes to make things easily
configurable with Guice + Jsecurity + Hibernate + Stripes.. so I can share that project scaffold
if needed.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
|