Spring security 4 @PreAuthorize("hasRole()") 不起作用

Posted

技术标签:

【中文标题】Spring security 4 @PreAuthorize("hasRole()") 不起作用【英文标题】:Spring security 4 @PreAuthorize("hasRole()") not working 【发布时间】:2015-12-09 17:31:41 【问题描述】:

过去几天我一直在进行故障排除,但我似乎无法让表达式 hasRole 起作用。我正在使用 spring-security 4.0.1

我的 Spring Security xml

<bean id="expressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
<security:global-method-security pre-post-annotations="enabled">
    <security:expression-handler ref="expressionHandler"/>
</security:global-method-security>


<security:http auto-config="true" use-expressions="true">
    <security:access-denied-handler error-page="/403" />
    <security:intercept-url pattern="/login" access="permitAll" />
    <security:intercept-url pattern="/logout" access="permitAll" />
    <security:intercept-url pattern="/css/**/*.css" access="permitAll" />
    <security:intercept-url pattern="/fonts/*.*" access="permitAll" />

    <security:intercept-url pattern="/**" access="isAuthenticated()" />

    <security:form-login login-page="/login" login-processing-url="/login" default-target-url="/landing" authentication-failure-url="/login?error" authentication-success-handler-ref="loginSuccesHandler" />
    <security:logout logout-success-url="/login?logout" logout-url="/logout" invalidate-session="true" />

    <security:session-management session-fixation-protection="none"/>
</security:http>
<security:authentication-manager>
    <security:authentication-provider user-service-ref="userDetailsService">
       <security:password-encoder ref="passwordEncoder"/>
    </security:authentication-provider>
</security:authentication-manager>


<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    <property name="userDetailsService" ref="userDetailsService" />
    <property name="passwordEncoder" ref="passwordEncoder" />
</bean>

我所有的角色都存储在数据库中,并且具有类似于 link 中的 1 的架构。在我的自定义userDetailService 中,我将从数据库中加载它。我的角色价值观是这样的

PYRL-EMPPF-01
PYRL-EMPPF-02
PYRL-EMPPF-03

我什至尝试过添加前缀“ROLE_”,但似乎无法正常工作。

这是我如何使用 hasRole 表达式的示例代码。我正在尝试使用它来保护我的控制器方法。

@RequestMapping(value = "/URLABC", method = RequestMethod.GET)
@PreAuthorize("hasRole('ROLE_PYRL-EMPPF-01')")
public ModelAndView search(HttpSession session) throws Exception 
...

我试过@PreAuthorize("hasRole('ROLE_PYRL-EMPPF-01')")@PreAuthorize("hasRole('PYRL-EMPPF-01')") 都没有工作。

【问题讨论】:

你可以试试@Secured( "ROLE_PYRL-EMPPF-01" ) 【参考方案1】:

不知怎的,我设法偶然发现了答案

<bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler"/>
<security:global-method-security pre-post-annotations="enabled">
    <security:expression-handler ref="expressionHandler"/>
</security:global-method-security>

我只需要将这个 spring 配置从我的 spring security xml 配置放到 spring servlet 配置中。

这是我的 web.xml。以前上面的配置在 application-security.xml 中,现在我将它移到 dispatcher-servlet.xml 中。

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/dispatcher-servlet.xml
        /WEB-INF/application-security.xml
    </param-value>
</context-param>

也不要使用org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler。我已将其更改为使用org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler

如果有人能解释 2 ExpressionHandler 类之间的区别,那就太好了。

【讨论】:

以上是关于Spring security 4 @PreAuthorize("hasRole()") 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security入门(3-4)Spring Security 异常处理异常传递和异常获取

Spring Security:3. What’s New in Spring Security 4.2 (新功能)

Spring Security - 访问被拒绝(用户不是匿名的)spring-security-core-4.0.3.RELEASE

Grails 2.4.4 中的 Spring Security 插件问题

如何使用 Spring-Security 3 和 Hibernate 4 将 spring security xml 配置 hibernate 转换为 java config

Maven Repository 上 4.1.1 中的 spring-security-web 在哪里?