带有Spring Security的Amazon Cognito Oauth2

jal*_*raz 7 java spring-security oauth-2.0 amazon-cognito

我正在尝试使用"Cognito Oauth2"在资源服务器中实现Spring Security,但是我似乎找不到太多信息.关于它(或者甚至可能这样做).

我最接近的方法是使用"Nimbus + JOSE"来检查"访问令牌"与"JWKS"的有效性,并授予访问资源的权限.(类似于他们在此处提供的"API网关资源保护实施"示例:https://aws.amazon.com/es/blogs/mobile/integrating-amazon-cognito-user-pools-with-api-gateway /)

非常感激您的帮忙.

谢谢!

dde*_*ele 17

使用最新的Sprint Boot 2.x/Sprint Security 5.x的Oauth2的一个很好的起点可以在这里找到:https://spring.io/blog/2018/03/06/using-spring-security-5-to -integrate与-的OAuth -2-固定服务-例如-AS-的Facebook和- github上

它使用Facebook/Github作为示例,但您也可以将其应用于AWS Cognito.

这是使用Spring Security/Cognito OAuth2设置安全REST后端的最简单方法.您的后端将通过Spring Security加以保护,AWS Cognito将用作身份提供商.

您可以使用弹簧安全启动器设置一个vanilla spring boot应用程序,如本文所述,使用以下依赖项:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-oauth2-client</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-oauth2-jose</artifactId>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

并提供您的cognito配置(客户注册+提供商定义),如下所示:

spring:
  security:
    oauth2:
      client:
        registration:
          cognito-client-1:
            client-id: 391uhnjlr8v8kicm3cru6g1s8g
            client-secret: xxxxxxxxxxxxxxxxxxxxxxxxxx
            client-name: Cognito Code Grant
            provider: cognito
            scope: openid
            redirect-uri-template: http://localhost:8080/login/oauth2/code/cognito
            authorization-grant-type: authorization_code
        provider:
          cognito:
            authorization-uri: https://custom-domain.auth.eu-central-1.amazoncognito.com/oauth2/authorize
            token-uri: https://custom-domain.auth.eu-central-1.amazoncognito.com/oauth2/token
            user-info-uri: https://custom-domain.auth.eu-central-1.amazoncognito.com/oauth2/userInfo
            jwk-set-uri: https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_xxxxxxxxx/.well-known/jwks.json
            user-name-attribute: cognito:username
Run Code Online (Sandbox Code Playgroud)

就Cognito而言,您需要拥有一个用户池和身份池,其中包含几个用户和一个有效的应用客户端(client-id在Spring配置中)=

  • 秘密(= client-secret在春季配置中)
  • 正确的授权和范围(在这种情况下,我使用带有openid范围的authorization_code授权)
  • 正确的重定向回调(= redirect-uri-template在spring配置中)
  • Cognito中的域配置
  • 包含您的cognito用户池的JWK uri(jwk-set-uri在spring配置中)

在此输入图像描述

一切就绪后,Spring Boot应用程序将自动生成登录URL

在此输入图像描述

将您重定向到cognito登录页面,您可以在其中输入您的认证凭据

在此输入图像描述

验证成功后,您将能够进行安全的REST呼叫

在此输入图像描述

使用这样的REST控制器:

@RestController
public class ExampleController {

    @RequestMapping("/")
    public String email(Principal principal) {
        return "Hello " + principal.getName();
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 经过数小时的搜索...谢谢! (2认同)

Arj*_* SK 6

我们可以创建 Spring Boot 资源服务器,保留 Cognito 作为身份提供者。

Spring boot 资源服务器

依赖关系:

    <!--  Spring Security-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.security.oauth.boot</groupId>
        <artifactId>spring-security-oauth2-autoconfigure</artifactId>
        <version>2.0.1.RELEASE</version>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

春季安全配置:

EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class OAuth2ResourceServerSecurityConfiguration extends ResourceServerConfigurerAdapter {

  private final ResourceServerProperties resource;

  public OAuth2ResourceServerSecurityConfiguration(ResourceServerProperties resource) {
    this.resource = resource;
  }

  @Override
  public void configure(HttpSecurity http) throws Exception {

    http.cors();

    http.csrf().disable();

    http.authorizeRequests()
        .antMatchers("/api/public/**").permitAll()
        .antMatchers("/actuator/health").permitAll()
        .anyRequest().authenticated();
  }


  // Note: Cognito Converter
  @Bean
  public TokenStore jwkTokenStore() {
    return new JwkTokenStore(
        Collections.singletonList(resource.getJwk().getKeySetUri()),
        new CognitoAccessTokenConverter(),
        null);
  }
}
Run Code Online (Sandbox Code Playgroud)

Cognito 访问令牌转换器:

在这里,我们将 Cognito 声明转换为 Spring Security 可使用格式。

@Component
public class CognitoAccessTokenConverter extends JwtAccessTokenConverter {

  // Note: This the core part.
  private static final String COGNITO_GROUPS = "cognito:groups";
  private static final String SPRING_AUTHORITIES = "authorities";
  private static final String COGNITO_USERNAME = "username";
  private static final String SPRING_USER_NAME = "user_name";

  @SuppressWarnings("unchecked")
  @Override
  public OAuth2Authentication extractAuthentication(Map<String, ?> claims) {

    if (claims.containsKey(COGNITO_GROUPS))
      ((Map<String, Object>) claims).put(SPRING_AUTHORITIES, claims.get(COGNITO_GROUPS));
    if (claims.containsKey(COGNITO_USERNAME))
      ((Map<String, Object>) claims).put(SPRING_USER_NAME, claims.get(COGNITO_USERNAME));
    return super.extractAuthentication(claims);
  }
}
Run Code Online (Sandbox Code Playgroud)

应用程序属性

server:
  port: 8081
security:
  oauth2:
    resource:
      userInfoUri: https://<cognito>.auth.eu-west-1.amazoncognito.com/oauth2/userInfo
      tokenInfoUri: https://<cognito>.auth.eu-west-1.amazoncognito.com/oauth2/token
      jwk:
        key-set-uri: https://cognito-idp.<region>.amazonaws.com/<user-pool-id>/.well-known/jwks.json
    client:
      clientId: <client-id>
Run Code Online (Sandbox Code Playgroud)

有关完整文章,请参阅:将 Spring Boot 资源服务器与 Cognito 身份提供程序集成