Spring @RestController 用于匿名和授权用户的单一方法

Posted

技术标签:

【中文标题】Spring @RestController 用于匿名和授权用户的单一方法【英文标题】:Spring @RestController single method for anonymous and authorized users 【发布时间】:2017-06-14 02:23:34 【问题描述】:

我有以下 Spring RestController:

@RestController
@RequestMapping("/v1.0/tenants")
public class TenantController 

    @Autowired
    private TenantService tenantService;

    @RequestMapping(value = "/tenantId", method = RequestMethod.GET)
    public TenantResponse findTenantById(@PathVariable @NotNull @DecimalMin("0") Long tenantId) 
        Tenant tenant = tenantService.findTenantById(tenantId);
        return new TenantResponse(tenant);
    


findTenantById 方法应该由匿名和授权用户访问。如果是匿名用户 SecurityContextHolder.getContext().getAuthentication() 必须返回 NULL 或 AnonymousAuthenticationToken 但如果是授权 - 身份验证对象。

在我的应用程序中,我使用 OAuth2 + JWT 令牌实现了安全模型。

这是我的配置:

    @Override
    public void configure(HttpSecurity http) throws Exception 
        // @formatter:off
        http                
            .antMatcher("/v1.0/**").authorizeRequests()
            .antMatchers("/v1.0/tenants/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .csrf().disable()
            .sessionManagement().sessionCreationPolicy(STATELESS); 
        // @formatter:on
    

此外,对于安全端点,我将在需要的地方应用 @PreAuthorize 注释,但在 findTenantById 的情况下不应用,因为正如我之前所说,我需要授予匿名和授权用户访问此端点的权限。在端点业务逻辑内部,我将根据不同的条件决定谁能够继续。

现在,即使我为此端点提供了我的accessToken,我也无法从SecurityContextHolder.getContext().getAuthentication() 获取经过身份验证的用户对象。

如何配置此端点以便以上述方式工作?

【问题讨论】:

Permit all 应该允许所有用户调用控制器方法。如果你曾经在代码中调用SecurityContextHolder.getContext().getAuthentication(),你很可能做错了什么。如果你需要知道用户是谁,你应该在控制器方法中包含 Authentication auth,Spring 会为你注入它,就像 ModelSession 和一堆其他类型一样。 【参考方案1】:

我想我已经找到了解决方案 - 我已经用以下方式注释了我的方法:

@PreAuthorize("isAnonymous() or isFullyAuthenticated()")

如果有更好的解决方案,请告诉我。

【讨论】:

是的,你是对的。我在我的业务逻辑中发现了一个问题,这是导致此问题的原因。现在一切都与permitAll 完美配合。谢谢。

以上是关于Spring @RestController 用于匿名和授权用户的单一方法的主要内容,如果未能解决你的问题,请参考以下文章

@component@RestController

@Controller 和 @RestController 区别是什么

Spring Boot 注释

Spring @RestController,spring-boot 出现意外错误(类型=不可接受,状态=406)

spring4.0之三:@RestController

Spring 注解中@RestController与@Controller的区别