使用 Cognito IAM 角色的端点上的 Spring 安全性?

Posted

技术标签:

【中文标题】使用 Cognito IAM 角色的端点上的 Spring 安全性?【英文标题】:Spring security on endpoint using Cognito IAM role? 【发布时间】:2021-12-29 11:59:54 【问题描述】:

我正在尝试根据它们在 OAuth2 凭据中设置的角色来限制 Spring 引导服务上的特定端点。

这是终点

@RestController
@RequestMapping("/api/admin")
public class AdminController 

    @GetMapping(produces = "application/json")
    public TestResponse get() 
        return new TestResponse("Admin API Response");
    

然后使用 SecurityConfiguration bean 对其进行保护

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 

    @Override
    protected void configure(HttpSecurity http) throws Exception 

        http.csrf()
            .and()
            .authorizeRequests()
            .antMatchers("/login", "/", "/home", "/logout", "/ping").permitAll()
            .antMatchers("/api/admin").hasRole("arn:aws:iam::xxxxxx:role/spring-sso-test-ADMIN")
            .antMatchers("/api/user").hasRole("arn:aws:iam::xxxxxx:role/spring-sso-test-USER")
            .and()
            .oauth2Login()
            .and()
            .logout()
            .logoutSuccessUrl("/logout");
    

我调试了Principal,可以在cognito:roleslist属性列表中看到正确的IAM角色

但是,当我点击端点时,我得到了 HTTP 403 Unauthorized。意思是用户已经认证成功,但是 Spring 不识别或不理解属性或者如何映射它们?

我尝试使用 @Secured 注释,但这并没有改变任何东西。

@Secured("arn:aws:iam::xxxxxx:role/spring-sso-test-ADMIN")
@GetMapping(produces = "application/json")
public TestResponse get() 
        return new TestResponse("Admin API Response");

如何使用在 AWS Cognito 中定义的 IAM 角色来允许它工作?

【问题讨论】:

【参考方案1】:

当您使用hasRole DSL 方法时,Spring Security 会为您的权限添加ROLE_ 前缀。所以,arn:aws:iam::xxxxxx:role/spring-sso-test-ADMIN 的权限会变成ROLE_arn:aws:iam::xxxxxx:role/spring-sso-test-ADMIN

您应该改用hasAuthority 方法。

此外,您应该从attributes 中取出cognito:roles 并添加authorities,因为这是Spring Security 将查询以获取权限的属性。

要映射权限,您可以使用OAuth2UserService


@Bean
SecurityFilterChain app(HttpSecurity http) throws Exception 
    http
            .oauth2Login(oauth2 -> oauth2
                .userInfoEndpoint(userInfo -> userInfo
                    .oidcUserService(this.oidcUserService())
                    ...
                )
            );
    return http.build();


private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() 
    // your custom implementation

更多详情请关注documentation。

【讨论】:

我刚刚尝试了这个hasAuthority("arn:aws:iam::xxxxxx:role/spring-sso-test-ADMIN"),但仍然得到 HTTP 403 logging.level.org.springframework.security=TRACE 添加到您的application.properties 并将日志粘贴到您的问题中 查看我的更新答案

以上是关于使用 Cognito IAM 角色的端点上的 Spring 安全性?的主要内容,如果未能解决你的问题,请参考以下文章

从 Cognito 组担任 IAM 角色

使用 Cognito UnAuth 角色时的 IAM 权限问题

Cognito 授权人组

AWS Lambda 无法调用 Cognito Identity - IAM 角色

有啥方法可以限制 IAM 用户/假定角色在 AWS cognito 中启用未经身份验证的用户身份?

如何在 IAM 角色的信任策略中检查自定义 OpenID 声明?