gpt4 book ai didi

spring - 如何配置 Spring Boot 以使用 AWS Cognito (OAuth2/OIDC) 对 Web 应用程序用户和 REST 客户端进行身份验证

转载 作者:行者123 更新时间:2023-12-03 08:07:00 24 4
gpt4 key购买 nike

我需要配置 Spring Boot 服务器来使用 AWS Cognito 用户池对 Web 用户和 REST 客户端进行身份验证:

  1. 使用 ReachJS 前端的交互式/Web 用户应重定向到 Cognito 进行身份验证,并在验证用户凭据后重定向回来。
  2. 直接使用服务器 REST API 的其他计算机应从 Cognito 获取 token 并将其作为 Authorization: Bearer ... header 发送到我的服务器。

问题是:

  1. 如何配置 spring 使用 Cognito 进行身份验证
  2. 如何让 spring 同时支持这两种不同类型的身份验证

最佳答案

概述

让我们从术语开始:

  1. IDP(身份提供商)是提供用户管理和身份验证服务的第三方,在我的例子中是 AWS Cognito。
  2. 通过将交互/Web 用户重定向到 IDP 进行身份验证,在 OAuth2/OIDC 中称为“授权代码授予流程”。
  3. 客户端向 REST API 发送 JWT token 称为“客户端凭据流程”。

Spring的spring-security-oauth2-client模块负责“授权代码授予流程”,spring-security-oauth2-resource-server模块负责对于“客户端凭据流程”。

为了同时使用这两种流程/方法,我们需要告诉 spring 如何确定对传入的 HTTP 请求使用哪种身份验证方法。如 https://stackoverflow.com/a/64752665/2692895 中所述,这可以通过查找 Authorization: bearer ... header:

来完成
  1. 如果请求包含 Authorization header ,则假定其为 REST 客户端并使用“客户端凭据流程”。
  2. 否则,它是一个交互式用户,如果尚未经过身份验证,则会重定向到 Cognito。

依赖项

我正在使用 Spring-Boot 2.6.6(Spring 5.6.2)。

        <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>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-resource-server</artifactId>
</dependency>

外部配置 - application.yaml

spring:
security:
oauth2:
# Interactive/web users authentication
client:
registration:
cognito:
clientId: ${COGNITO_CLIENT_ID}
clientSecret: ${COGNITO_CLIENT_SECRET}
scope: openid
clientName: ${CLIENT_APP_NAME}
provider:
cognito:
issuerUri: https://cognito-idp.eu-central-1.amazonaws.com/${COGNITO_POOL_ID}
user-name-attribute: email

# REST API authentication
resourceserver:
jwt:
issuer-uri: https://cognito-idp.eu-central-1.amazonaws.com/${COGNITO_POOL_ID}

Spring 安全配置

交互式/网络用户身份验证:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
// Needed for method access control via the @Secured annotation
prePostEnabled = true,
jsr250Enabled = true,
securedEnabled = true
)
@Profile({"cognito"})
@Order(2)
public class CognitoSecurityConfiguration extends WebSecurityConfigurerAdapter {

@SneakyThrows
@Override
protected void configure(HttpSecurity http) {
http
// TODO disable CSRF because when enabled controllers aren't initialized
// and if they are, POST are getting 403
.csrf().disable()

.authorizeRequests()
.anyRequest().authenticated()

.and()
.oauth2Client()

.and()
.logout()

.and()
.oauth2Login()
.redirectionEndpoint().baseUri("/login/oauth2/code/cognito")
.and()
;
}
}

REST 客户端身份验证:

/**
* Allow users to use a token (id-token, jwt) instead of the interactive login.
* The token is specified as the "Authorization: Bearer ..." header.
* </p>
* To get a token, the cognito client-app needs to support USER_PASSWORD_AUTH then use the following command:
* <pre>
* aws cognito-idp initiate-auth --auth-flow USER_PASSWORD_AUTH --output json \
* --region $region --client-id $clientid --auth-parameters "USERNAME=$username,PASSWORD=$password" \
* | jq .AuthenticationResult.IdToken
* </pre>
*/
@Slf4j
@Configuration
@Profile({"cognito"})
@Order(1)
public class CognitoTokenBasedSecurityConfiguration extends WebSecurityConfigurerAdapter {

@SneakyThrows
@Override
protected void configure(HttpSecurity http) {
http
.requestMatcher(new RequestHeaderRequestMatcher("Authorization"))
.authorizeRequests().anyRequest().authenticated()
.and().oauth2ResourceServer().jwt()
;
}

}

Cognito 配置说明

  • 在 AWS Cognito 中,您需要创建一个用户池和两个客户端应用程序,一个用于交互式/Web 用户的“公共(public)客户端”,一个用于基于 token 的 REST 客户端的“ secret 客户端”。
  • 在“公共(public)客户端”中,确保为您的所有环境(本地主机、生产环境等)定义“允许的回调 URL”,它们都应类似于 http://localhost:8080/login/oauth2/code/cognito(当然有正确的主机名和端口)。

关于spring - 如何配置 Spring Boot 以使用 AWS Cognito (OAuth2/OIDC) 对 Web 应用程序用户和 REST 客户端进行身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71982171/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com