带有 Spring Security 的 Amazon Cognito Oauth2
Posted
技术标签:
【中文标题】带有 Spring Security 的 Amazon Cognito Oauth2【英文标题】:Amazon Cognito Oauth2 with Spring Security 【发布时间】:2018-06-27 21:13:10 【问题描述】:我正在尝试使用“Cognito Oauth2”在资源服务器中实现 Spring Security,但是我似乎没有找到太多信息。关于它(或者如果它甚至可能这样做)。
我最近的方法是使用“Nimbus+JOSE”通过“JWKS”检查“访问令牌”的有效性,并授予访问资源的权限。 (类似于他们在此处找到的“API 网关资源保护实施”示例:https://aws.amazon.com/es/blogs/mobile/integrating-amazon-cognito-user-pools-with-api-gateway/)
【问题讨论】:
【参考方案1】:Baeldung 网站上有一个具体示例说明如何执行此操作
https://www.baeldung.com/spring-security-oauth-cognito
【讨论】:
【参考方案2】:我们可以创建 Spring Boot 资源服务器,保持 Cognito 作为身份提供者。
依赖:
<!-- 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>
Spring 安全配置:
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);
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);
application.properties
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>
完整文章请参考:Integrate Spring Boot Resource Server with Cognito Identity Provider
【讨论】:
我喜欢这个解决方案,但ResourceServerProperties
在春季已被弃用...
如今,REST API 通常通过具有 Cognito 集成的 API-Gateway 托管。
有趣,虽然我计划使用 API-GW,但我并没有考虑过这个选项。会看那个。但是,不能解决已弃用的问题:)
@Louis-wht,您能否分享任何参考链接,说明此弃用。我看到 spring-boot-starter-oauth2-resource-server
已在 2020 年 1 月推出了最新版本。
这个答案的核心是指出CognitoAccessTokenConverter
,它将Cognito claims
转换为spring-security
格式。我认为,在迁移之后,您可能仍需要相同的解决方案来进行 cognito 集成。【参考方案3】:
可以在这里找到使用最新 Sprint Boot 2.x / Sprint Security 5.x 的 Oauth2 的一个很好的起点:https://spring.io/blog/2018/03/06/using-spring-security-5-to-integrate-with-oauth-2-secured-services-such-as-facebook-and-github
它使用 Facebook / Github 作为示例,但您也可以将其应用于 AWS Cognito。
这是迄今为止使用 Spring Security / Cognito OAuth2 设置安全 REST 后端的最简单方法。您的后端将通过 Spring Security 得到保护,AWS Cognito 将用作身份提供者。
您可以使用文章中概述的 spring security starter 设置一个 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>
并像这样提供您的 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
就 Cognito 而言,您需要在 cognito 中拥有一个包含几个用户的用户池/身份池和一个有效的应用客户端(= client-id
in spring config)
client-secret
在 spring 配置中)
正确的授权和范围(在这种情况下,我使用的是带有 openid 范围的授权代码授权)
正确的重定向回调(= redirect-uri-template
在 spring 配置中)
cognito 中的域配置
包含您的 cognito 用户池的 JWK uri(spring 配置中的jwk-set-uri
)
一切就绪后,Spring Boot 应用会自动生成登录 url
将您重定向到 cognito 登录页面,您可以在其中输入您的 cognito 凭据
在成功验证后,您将能够进行安全的 REST 调用
使用这样的 REST 控制器:
@RestController
public class ExampleController
@RequestMapping("/")
public String email(Principal principal)
return "Hello " + principal.getName();
【讨论】:
我也在努力创造这些东西,却不知道这一切都是在春天处理的。至于对我帮助最大的 Cognito 资源是:github.com/aws-quickstart/saas-identity-cognito 您如何管理注销?我有弹簧在注销后自动登录,所以用户不会被注销 试图解决同样的问题 Kappa。看看这个:docs.aws.amazon.com/pt_br/cognito/latest/developerguide/… @AlexandreMucci 感谢您的提示,我已经阅读了注销端点文档,但是在使 HTTP 会话无效并删除 cookie 之前注销时,spring security 似乎没有调用此类端点;所以我的用户实际上并没有被注销。此外,对我来说似乎很奇怪的是,在下一个请求中没有 cookie、没有本地存储数据和没有其他标头参数会自动让我再次登录(但只能从同一个浏览器的同一个选项卡) @smac2020 你完成了吗?如果是的话,你能分享一下官方文档吗?以上是关于带有 Spring Security 的 Amazon Cognito Oauth2的主要内容,如果未能解决你的问题,请参考以下文章
带有 OpenIDAuthenticationFilter 问题的 Spring Security
带有 spring-boot 和 spring-security 的 JWT
带有 Spring Security 的 Spring REST 不接受凭据
带有 LDAP 注销的 Spring Security 无法删除会话
如何使用带有多个过滤器和 Spring Security 的 Spring DelegatingFilterProxy?
我们如何使用带有 Spring 5.0 的最新 spring-security-oauth2 jar 来实现授权服务器?