Spring安全性允许任何类型的角色(ROLE_USER / ROLE_ADMIN)访问资源

时间:2014-12-23 09:28:21

标签: jsf-2 spring-security

我想将spring security与jsf集成,我遇到的问题是Spring安全性不会过滤对资源的访问,即ROLE_USER可以访问xhtml,其访问权限已定义为" ROLE_ADMIN"。 我的spring-security配置文件:

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:sec="http://www.springframework.org/schema/security" 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">

    <!-- Enable method level Spring Security by annotations -->
    <sec:global-method-security pre-post-annotations="enabled" />

    <sec:http auto-config="true" use-expressions="true">
        <sec:intercept-url pattern="/javax.faces.resource/*" access="permitAll" />
        <sec:intercept-url pattern="/pages/login.xhtml" access="permitAll" />
        <sec:intercept-url pattern="/pages/index.xhtml" access="permitAll" />
        <sec:intercept-url pattern="/pages/admin/admin.xhtml" access="hasRole('ROLE_ADMIN')" />
        <sec:form-login login-page="/pages/login.xhtml"
            authentication-failure-url="/pages/login.xhtml?error=true"
            authentication-success-handler-ref="loginSuccessHandler" />
        <sec:logout logout-success-url="/pages/login.xhtml" />
    </sec:http>
    <bean id="serviceManager"
        class="com.souhaieb.education.cursus.security.SecurityManagerSupport" />

    <sec:authentication-manager alias="authenticationManager">
        <sec:authentication-provider user-service-ref="serviceManager">
            <sec:password-encoder hash="plaintext"></sec:password-encoder>
        </sec:authentication-provider>
    </sec:authentication-manager>
    <bean id="loginSuccessHandler"
        class="com.souhaieb.education.cursus.security.LoginSuccessHandler" />
</beans>

managedbean中的登录方法:

public String login() {
    try {
        Authentication request = new UsernamePasswordAuthenticationToken(user.getUserName(), user.getPassword());
        Authentication result = authenticationManager.authenticate(request);
        SecurityContextHolder.getContext().setAuthentication(result);
    } catch (AuthenticationException e) {
        e.printStackTrace();
        return "pretty:error";
    }
    return "pretty:home"; // pages/index.xhtml
}

这里是UserDetailsS​​ervice的实现

public class SecurityManagerSupport implements UserDetailsService {

@Autowired
private AuthenticationService authenticationService;

public UserDetails loadUserByUsername(final String userName)
        throws UsernameNotFoundException {
    com.souhaieb.education.cursus.ws.client.authentication.User user = authenticationService.getUserByUserName(userName);
    if(user == null){
        throw new UsernameNotFoundException(userName+ " not found");
    }
    /*PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    user.setPassword(passwordEncoder.encode(user.getPassword()));*/
    String username = user.getUserName();
    String password = user.getPassword();
    boolean enabled = user.isEnabled();
    boolean accountNonExpired = true;
    boolean credentialsNonExpired = true;
    boolean accountNonLocked = true;
    return new User(username, password, enabled, accountNonExpired,
                credentialsNonExpired, accountNonLocked, getAuthorities(user.getUserRoleList().getUserRoles()));

}
.
.
.

的web.xml

    <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">

    <display-name>Cursus Management</display-name>

    <!-- <context-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </context-param> -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext-security.xml
            /WEB-INF/applicationContext.xml
        </param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>server</param-value>
    </context-param>
    <context-param>
        <param-name>com.ocpsoft.pretty.DEVELOPMENT</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>primefaces.THEME</param-name>
        <param-value>bootstrap</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

    <listener>
        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
    </listener>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

    <filter-mapping>
        <filter-name>Pretty Filter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter>
        <filter-name>Pretty Filter</filter-name>
        <filter-class>com.ocpsoft.pretty.PrettyFilter</filter-class>
    </filter>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

1 个答案:

答案 0 :(得分:1)

问题是页面的<sec:intercept-url pattern>。我应该使用URL而不是JSF视图ID。例如,/admin而不是/pages/admin/admin.xhtml。我使用PrettyFaces来获取友好的URL,这让我很困惑。

<sec:http auto-config="true" use-expressions="true">
    <sec:intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')" />
    <sec:intercept-url pattern="/login" access="permitAll" />
    <sec:intercept-url pattern="/home" access="permitAll" />
    <sec:form-login login-page="/login"
        authentication-success-handler-ref="loginSuccessHandler" />
    <sec:logout logout-success-url="/login" />
</sec:http>