【问题标题】:Spring security allows any type of role (ROLE_USER/ROLE_ADMIN) to access to resourcesSpring Security 允许任何类型的角色(ROLE_USER/ROLE_ADMIN)访问资源
【发布时间】:2015-02-21 10:14:48
【问题描述】:

我想将 spring security 与 jsf 集成,我遇到的问题是 spring security 不会过滤对资源的访问,即 ROLE_USER 可以访问其访问定义为“ROLE_ADMIN”的 xhtml。 我的 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>

【问题讨论】:

  • 我没听懂,你在 spring-security 中寻找 hasAnyRole 吗?
  • 不,我希望只有角色“USER_ADMIN”的用户将被定向到 index.xhtml,这就是我定义的()
  • @user23123412 我使用 hasRole 但总是同样的问题。 spring-security 不控制对资源的访问
  • 您是否将 Spring Security 的 springSecurityFilterChain 添加到您的 web.xml 文件中?如果有,你能提供吗?
  • @RobWinch 是的,我添加了它

标签: jsf-2 spring-security


【解决方案1】:

问题是页面的&lt;sec:intercept-url pattern&gt;。我应该使用 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-03
    • 2021-10-04
    • 2016-11-18
    • 2015-07-01
    • 2014-04-11
    • 1970-01-01
    • 2015-05-25
    相关资源
    最近更新 更多