@PreAuthorize注释不起作用的弹簧安全性

Rah*_*eel 24 java spring spring-security

我发现了许多类似的问题但没有一个能解决我的问题.我的问题是ROLE_USER可以访问的功能ROLE_ADMIN

我的spring-security.xml代码如下.

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:s="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-3.0.xsd
                    http://www.springframework.org/schema/security
                    http://www.springframework.org/schema/security/spring-security-3.0.xsd">   

<s:http auto-config="true" use-expressions="true">
    <s:intercept-url pattern="/index.jsp" access="permitAll" />
    <s:intercept-url pattern="/welcome*" access="hasRole('ROLE_USER')" />
    <s:intercept-url pattern="/helloadmin*" access="hasRole('ROLE_ADMIN')" />

    <s:form-login login-page="/login" default-target-url="/welcome"
        authentication-failure-url="/loginfailed" />
    <s:logout logout-success-url="/logout" />
</s:http>

<s:authentication-manager>
  <s:authentication-provider>
    <s:user-service>
        <s:user name="asif" password="123456" authorities="ROLE_USER,ROLE_ADMIN" />
        <s:user name="raheel" password="123456" authorities="ROLE_USER" />          
    </s:user-service>
  </s:authentication-provider>
</s:authentication-manager>
Run Code Online (Sandbox Code Playgroud)

当我添加<s:global-method-security pre-post-annotations="enabled"/> 我的代码显示资源未找到错误,当我删除我的代码执行成功但ROLE_USER可以访问ROLE_ADMIN功能

我的控制器功能是.

@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value="/delete", method = RequestMethod.GET)
public String DeleteAll(ModelMap model, Principal principal ) {

    org.springframework.security.core.userdetails.User activeUser = (org.springframework.security.core.userdetails.User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    System.out.println("Active user is "+activeUser.getUsername()+"Authorities are "+activeUser.getAuthorities());
    return "deleteUsers";

}
Run Code Online (Sandbox Code Playgroud)

Sam*_*nia 32

如果您使用的是XML配置,请不要忘记添加以下属性:

<s:global-method-security pre-post-annotations="enabled"/>

如果您使用的是Java配置,请不要忘记添加以下注释:

@EnableGlobalMethodSecurity(prePostEnabled = true)


Sim*_*eon 27

你应该有

<s:global-method-security pre-post-annotations="enabled"/>
Run Code Online (Sandbox Code Playgroud)

如果您希望@PreAuthorize注释工作.


回答评论:

看起来你错过了spring-aop依赖.

如果你正在使用maven,你需要:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>${org.springframework.version}</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

如果没有,你可以从这里拿到罐子.


Geo*_*lou 14

我面临同样的问题.当我将下面的元素从applicationContext.xml移动到*-servlet.xml(我的调度程序的配置xml)时,我的问题解决了.

<security:global-method-security secured-annotations="enabled"/>
Run Code Online (Sandbox Code Playgroud)

您必须在调度程序的xml上包含此元素,而不是在应用程序的xml上.
Spring FAQ

  • 如果您至少没有在 servlet 的 xml 配置中定义 global-security-method,这绝对是正确的答案- (2认同)

Ale*_*mon 7

使用注释时,我遇到了同样的问题,问题是我的控制器中没有@Controller注释。


所以看来您需要:

  • Spring Security配置中的这些注释:

    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    
    Run Code Online (Sandbox Code Playgroud)
  • 这些注释在您的控制器中:

    @Controller
    public class ServiceRS {
    
        @RequestMapping(value = "/admin", method = RequestMethod.GET)
        @PreAuthorize("hasAuthority('ROLE_ADMIN')")
        public void wsAdmin() {
            [...]
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

另外,如果仍然有问题,请考虑将其添加到log4j2配置中:

    <Logger name="org.springframework.security" level="trace" additivity="false">
        <AppenderRef ref="Console" />
        <AppenderRef ref="RollingRandomAccessFile" />
    </Logger>
Run Code Online (Sandbox Code Playgroud)

您将在日志中看到Spring是否考虑了您的注释:

TRACE org.springframework.security.access.prepost.PrePostAnnotationSecurityMetadataSource {} [main] Looking for Pre/Post annotations for method 'wsAdmin' on target class '***.ServiceRS' 
DEBUG org.springframework.security.access.prepost.PrePostAnnotationSecurityMetadataSource {} [main] @org.springframework.security.access.prepost.PreAuthorize(value=hasAuthority('ROLE_ADMIN')) found on specific method: public void ***.ServiceRS.wsAdmin() 
DEBUG org.springframework.security.access.method.DelegatingMethodSecurityMetadataSource {} [main] Caching method [CacheKey[***.ServiceRS; public void ***.ServiceRS.wsAdmin()]] with attributes [[authorize: 'hasAuthority('ROLE_ADMIN')', filter: 'null', filterTarget: 'null']] 
Run Code Online (Sandbox Code Playgroud)

很显然,您可以考虑在org.springframework.security.access.expression.SecurityExpressionRoot中的相应方法中添加断点,以查看是否对注释中的条件进行了调用。

问候。