Reputation: 23
I am hoping that someone can help me with integrating the @PreAuthorize annotation with managed beans. I have been trying to get this to work for the last few hours but apparently there is something I am missing. My research on the web has shown that the global-method-security element can be used with spring or with aspectj. Since I don't want to declare my managed beans as spring beans I have chosen to use aspectj. For some reason though the PreAuthorize annotation is completely ignored. I am not getting any errors and everything compiles and runs fine but there is no security check on the managed bean. Apparently aspectj requires some kind of weaving??? Maybe I am approaching this wrong way and there is an easier way..not sure. Using Tomcat 7 with JSF 2.2 and Spring Security 4. I have the annotation on the class but that may be my problem. I am under the assumption that putting it on the class will use its default constructor method.
Can someone please advise? (configs below)
security.xml
<b:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<http use-expressions="true">
<headers>
<frame-options policy="SAMEORIGIN" />
</headers>
<intercept-url pattern="/admin/**" access="hasRole('Admin')" />
<intercept-url pattern="/cms/**" access="hasAnyRole('Admin','CMS_Admin')" />
<form-login login-page='/login' default-target-url="/" />
<logout invalidate-session="true" logout-success-url="/" />
<csrf disabled="true"/>
</http>
<b:bean name="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<b:bean name="iberisUserDetailsService" class="com.bizznetworxonline.iberis.core.web.controllers.admin.security.IberisUserDetailsService"/>
<authentication-manager>
<authentication-provider user-service-ref='iberisUserDetailsService'>
<password-encoder ref="bcryptEncoder"/>
</authentication-provider>
</authentication-manager>
<global-method-security mode="aspectj" pre-post-annotations="enabled" proxy-target-class="true">
</global-method-security>
</b:beans>
Maven build
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.8</version>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
Managed Bean
@ManagedBean
@ViewScoped
@PreAuthorize("hasAnyRole('Admin')")
public class ProductManagement
Upvotes: 1
Views: 891
Reputation: 31679
As you're instructing JSF to create your bean and not Spring, @PreAuthorize
makes little sense there. Even when using Spring to create the bean, its use is targeted to methods (even if you can annotate a class to have all its methods processed):
@PreAuthorize("hasRole('ROLE_USER')")
public void create(Contact contact);
Here Spring checks if the current logged user has the USER Role, in order for him to be able to create a contact.
It seems what you want to restrict in your question is the access to a whole view, so why not go the same way as you do in your security.xml declaration?
<intercept-url pattern="/products/product_management.xhtml" access="hasRole('USER')" />
This way Spring security checks the permission in its Web Filter, which is even better.
See also:
Upvotes: 3