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

Spring security on endpoint using Cognito IAM role?

我正在尝试限制 Spring 引导服务上的特定端点,具体取决于它们在 OAuth2 凭据中设置的角色。

这是终点

@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,可以在属性列表中看到正确的 IAM 角色 cognito:roles 列表

但是,当我到达端点时,我收到 HTTP 403 未经授权。意思是用户已经认证成功,但是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 角色允许它工作?

当您使用 hasRole DSL 方法时,Spring 安全性会将 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 安全性将查询 属性得到当局。

要映射权限,您可以使用 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 中有更多详细信息。