How to use role-hierarchy in Spring Security 3 with Spring EL? - spring

I want to use #PreAuthorize annotation on service methods with Spring Security. One of requirements is to use role-hierarchy. But by default it is not enabled.
I found that in SecurityExpressionRoot class ("the base class for expression root objects") there is a property roleHierarchy. The class actually does use this property for methods like hasRole() and hasAnyRole().
I suppose that if I supply it with my own RoleHierarchy bean I will be able to use #PreAuthorize annotations with hierarchical roles.
How can I inject my hierarchy bean into SecurityExpressionRoot?

For method security you can set RoleHierarchy as a property of DefaultMethodSecurityExpressionHandler, something like this:
<global-method-security ...>
<expression-handler ref = "methodSecurityExpressionHandler" />
</global-method-security>
<beans:bean id = "methodSecurityExpressionHandler"
class = "org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
<beans:property name = "roleHierarchy" .../>
</beans:bean>

Related

what is the usage of new keyword while using java configuration in spring

I have a question around the usage of new keyword being used when using java configuration in spring. What is the need of using new keyword
Refer below mentioned example:
Code implemented using Java Config
#Configuration
public class HelloWorldConfig {
#Bean
public HelloWorld helloWorld(){
return new HelloWorld();
}
}
The above code will be equivalent to the following XML configuration
<beans>
<bean id = "helloWorld" class = "com.test.HelloWorld" />
</beans>
In XML config, we do not use new keyword whereas in java config we are using new keyword. can someone please explain the difference
In the XML configuration, you explain to the system what class should be instanciated (there is a "new" but it is behind the scene) but in the Java Config you actually have to return an instance so that is why we use the 'new' keyword. 'new' simply creates an instance of your class.
The two examples shown in question are not really equivalent.
What the
<beans>
<bean id="helloWorld"
class="com.test.HelloWorld" />
</beans>
really does, is it tells Spring to instantiate class com.test.HelloWorld, and name the resulting bean "helloWorld".
Then the java-config approach is not really doing this. Instead this follows the factory-method pattern, when we tell Spring, that the return value of the method is the bean, and the method name is the name of that bean.
An equivalent of that in XML would be the mentioned factory-method approach, which in this case would look something like this:
<beans>
<bean id="helloWorldConfig"
class="com.test.HelloWorldConfig" />
<bean id="helloWorld"
factory-bean="helloWorldConfig"
factory-method="helloWorld" />
</beans>
Note that there are several approaches to factory-method. In the above, we are assuming, the `helloWorldConfig" is the factory, and we're specifying the method on that bean. Theare are cases with static factory methods too. See here for more examples.
<beans>
<bean id = "helloWorld" class = "com.test.HelloWorld" />
</beans>
This XML configurations tells Spring to "create an instance of com.test.HelloWorld and put it in the bean context with bean id helloWorld".
#Configuration
public class HelloWorldConfig {
#Bean
public HelloWorld helloWorld(){
return new HelloWorld();
}
}
In this Java configuration, we are returning an instance of com.test.HelloWorld. Because of the #Bean annotation, this instance is put into the bean context. As no specific bean id is given, the bean id is derived from the method hellowWorld() and thus becomes helloWorld.
As you can see, both configurations require an instance of com.test.HelloWorld. The XML configuration implicitly creates the instance whereas in the Java configuration you have to explicitly do it yourself.

In Spring, how can I autowire a property of a bean?

I’m using Spring 3.2.11.RELEASE. I have the following bean …
<beans:bean id=“customAuthenticationFilter"
class="org.mainco.subco.core.security.CustomAuthenticationFilter">
<beans:property name="filterProcessesUrl" value="/j_custom_value" />
…
From within one of my Spring classes, I’d like to figure out the value of the “filterProcessUrl” property. I could do something like
#Autowired
private CustomAuthenticationFilter myFilter
…
String value = myFilter.getFilterPRocessesUrl();
but I wanted to see if I could somehow outwore the “filterProcessesUrl” value into a member field (essentially boiling the above two lines of code into one). How would I go about doing this?

Get session proxy bean in JSP

I have a session bean like this:
#Component
#Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MySession { ... }
How can I enable access to this bean in JSP?
I displayed session data in JSP and I got this:
org.springframework.web.context.request.ServletRequestAttributes.DESTRUCTION_CALLBACK.scopedTarget.mySession
scopedTarget.mySession
So, I tried using ${scopedTarget.mySession.qualites}, but it didn't work.
If you expose spring beans as context properties using this view resolver configuration, then it should be possible to access the bean with a value expression such as #{mySession.qualites} directly:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="exposeContextBeansAsAttributes" value="true"/>
</bean>
As an alternative, expose the spring bean to the view model, by using in the #Controller the #ModelAttribute annotation.

Looking for a way to apply aspects to spring-mvc controller method

The original intention was to be able to configure filter mappings with annotations (i.e. #FilteredBy below) instead of adding filter mappings to the web.xml file. Something like:
#Controller
public class MyController {
#RequestMapping(value = "/special/page.html")
#FilteredBy("SpecialBean") // <-- *** desired ***
public String doSpecialStuff() {
return "special/page";
}
}
I see that Servlet 3.0 introduces #ServletFilter which can be applied any object method and the mappings are defined by #FilterMapping. However, I want invert the responsibility of the mapping to the controller method consuming the shared logic of my "SpecialBean".
Why not use your spring context xml. If you are using mvc:annotation you can try this.
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/filtered/page.htm" />
<bean class="com.yourinterceptor" />
</mvc:interceptor>
</mvc:interceptors>

Spring Injection can not find variable in resource file

I have a resource file created in my project. I want to inject values from resource file into spring bean. i defined the place holder for resource file in the applicacationContext.xml.
<context:property-placeholder location="file:///${MRAPOR_PROPPATH}mRapor.properties" />
I can inject values to beans which is declared in the applicationContext.xml like :
<bean
id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean" >
<property
name="jndiName"
value="${database.jndiName}" />
<property
name="lookupOnStartup"
value="false" />
<property
name="cache"
value="true" />
<property
name="proxyInterface"
value="javax.sql.DataSource" />
</bean>
This works well. However, i can not inject values if i declare beans with spring annotations.
#Component("SecurityFilter")
public class SecurityFilter implements Filter {
public static final String USER = "USER_SESSION_KEY";
public static final String CENTRIFY_USERNAME_KEY = "REMOTE_USERNAME";
#Value("${url.logout}")//I get error here !!!!
private String logoutUrl;
//proper setters and getters.
}
Do you have any idea why i can not access values inside the beans declared using annotations.
Here is my exception
weblogic.application.ModuleException:
at weblogic.servlet.internal.WebAppModule.startContexts(WebAppModule.java:1510)
at weblogic.servlet.internal.WebAppModule.start(WebAppModule.java:482)
at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:425)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:52)
at weblogic.application.internal.flow.ModuleStateDriver.start(ModuleStateDriver.java:119)
Truncated. see log file for complete stacktrace
Caused By: java.lang.IllegalArgumentException: Could not resolve placeholder 'url.logout' in string value [${url.logout}]
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:173)
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:125)
at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer$PlaceholderResolvingStringValueResolver.resolveStringValue(PropertyPlaceholderConfigurer.java:255)
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:748)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:745)
Are you sure that the instance of SecurityFilter that actually filters requests is managed by Spring?
By default Filters declared in web.xml are instantiated by servlet container, therefore they are not managed by Spring and Spring annotations such as #Value won't work in them.
However, Spring provides special support for your use case - you can delegate filtering to a component managed by Spring using DelegatingFilterProxy. Declare it in web.xml as follows:
<filter>
<filter-name>SecurityFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>...</filter-mapping>
DelegatingFilterProxy will delegate request filtering to a bean named SecurityFilter (as in your #Component).
The #Value is processed by the java compiler whereas the the XML is parsed by Spring Bean Processor - these are two very different things... Why do you assume that should work in the same manner?
Edit: I read up on it and it seems to actually be possible using the Spring EL, you only have to prefix with # instead of $:
private #Value( "#{application.url.logout}" ) String logoutUrl;
Cheers,

Resources