user2677597
user2677597

Reputation: 23

Spring Security 4 JSF Managed bean preauthorize annotation

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

Answers (1)

Aritz
Aritz

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

Related Questions