在 SpringBoot 应用程序中使用 @RolesAllowed 的异常

Posted

技术标签:

【中文标题】在 SpringBoot 应用程序中使用 @RolesAllowed 的异常【英文标题】:Exception using @RolesAllowed in SpringBoot app 【发布时间】:2017-10-20 12:34:10 【问题描述】:

我有一个基本的 SpringBoot 应用程序。使用 Spring Initializer、嵌入式 Tomcat、Thymeleaf 模板引擎,并打包为可执行 JAR 文件。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 
...

companyService 已注入且不为空。删除 @RolesAllowed 工作正常

@Autowired
CompanyService companyService;

在我的应用配置中:

@Configuration
@EnableGlobalMethodSecurity(jsr250Enabled=true, securedEnabled=true, prePostEnabled=true)

我有一个这样注释的控制器方法

@ModelAttribute("companies")
    @RolesAllowed("ROLE_ADMIN")
    public Iterable<Company> companies()
        return companyService.findAll();
    

当我尝试访问控制器时,我遇到了一个没有任何信息的应用程序异常:

<div th:utext="'Failed URL: ' +  $url"    th:remove="tag">$url</div>
<div th:utext="'Exception: ' + $message"  th:remove="tag">$message</div>
<div th:utext="'Exception: ' + $trace"    th:remove="tag">$trace</div>


<!--
    Failed URL: null
    Exception: No message available
    Exception: null

    -->

在到达控制器之前,我会检查用户的角色

System.out.println("Authorities -> " +
    SecurityContextHolder.getContext().getAuthentication().getAuthorities())

结果如下:

Authorities -> [Authority [authority=ROLE_BASIC], Authority [authority=ROLE_ADMIN]]

使用相同的结果:

  @ModelAttribute("companies")
    @Secured("ADMIN")
    public Iterable<Company> companies()
        return companyService.findAll();
    

@Secured("ROLE_ADMIN")

在调试中:

 42410 [http-nio-8080-exec-7] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@65eab2b2, returned: 1
42410 [http-nio-8080-exec-7] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
42410 [http-nio-8080-exec-7] DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
42410 [http-nio-8080-exec-7] DEBUG o.s.security.web.FilterChainProxy - /company/list reached end of additional filter chain; proceeding with original chain
42411 [http-nio-8080-exec-7] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
42411 [http-nio-8080-exec-7] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
42411 [http-nio-8080-exec-7] DEBUG o.a.c.c.C.[Tomcat].[localhost] - Processing ErrorPage[errorCode=0, location=/error

companies() 会在您删除 @Secured 时调用,并调试 AffirmativeBased 我得到了:

切换(结果) 案例 AccessDecisionVoter.ACCESS_GRANTED: 返回; logger.debug("授权成功");

【问题讨论】:

日志中没有堆栈跟踪吗? 不,日志中没有堆栈跟踪 您的应用是否要求用户身份验证? (即浏览器要求用户/密码)当您访问您的安全网址时? 是的,我的应用要求用户认证 您是否也有@EnableWebSecurity,并正确配置了AuthenticationManagerBuilder 【参考方案1】:

当您删除@Secured 注释时是否调用companies()? 如果是,则尝试调试 org.springframework.security.access.vote.AffirmativeBased 最有可能的是,首先它会在检查您的 url 时被调用,然后当您调用由@Secured 注释保护的companies() 方法时会调用它,并且由于某种原因第二次检查失败。

另见: https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#authz-pre-invocation

【讨论】:

【参考方案2】:

不要使用@Secured@RolesAllowed 不再推荐使用此注释。而是使用@PreAuthorize("hasAuthority('ROLE_ADMIN')")

【讨论】:

我得到了同样的错误:status=404, error=Not Found :-(

以上是关于在 SpringBoot 应用程序中使用 @RolesAllowed 的异常的主要内容,如果未能解决你的问题,请参考以下文章

@RolesAllowed 与 @PreAuthorize 与 @Secured

select2 占位符显示空选项

如何透视表?

sql TRIGGER ACTUALIZACION USUARIO ROL INSERTAR

在刀片中动态创建复选框

在初始化时加载 Spring Boot 属性并尊重所有属性并根据属性文件中的值控制 @Aspect