我使用带有自定义JWTFilter的Spring安全auth2来实现,它将从请求中获取令牌并再次验证cognito池的JWKs验证文件。
- 用户在用户界面中输入用户名/密码。
- UI调用后端应用程序,后者调用Cognito。
- Cognito返回JWT令牌(Idtoken,accessToken,refreshToken)
- 后端应用程序将IdToken作为令牌发送到UI,并存储在缓存中(也可以是任何数据库)。
- UI将此IDToken发送给下一次调用。
JWTFilter为身份验证执行以下步骤:
- 后端应用程序获取令牌,在缓存中进行验证(如果存在),然后使用Cognito JWK验证签名和有效期并从中获取详细信息。
- 后端应用程序创建扩展了AbstractAuthenticationToken的UserAuthentication,并从解析的令牌值填充详细信息并存储在上下文(会话)中
将按照网络安全配置中提到的配置对资源进行授权。
,
我们可以创建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 Security配置:
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声明转换为Spring Security消耗品格式。
对于授权,我们将使用Cognito组。我们创建两个组,ROLE_ADMIN和ROLE_EMPLOYEE。我们将用户映射到每个组。验证用户身份后,我们将Cognito组作为声明。我们利用它来为用户设置Spring Security Authority。
@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
,
您需要在Spring安全性中实现JWT令牌方法(可以使用spring security auth 2 impl。)
因此,身份验证步骤如下:
- 用户将在您的前端应用程序中输入其凭据。
- 您的身份验证服务会将这些凭证发送到AWS Cognito进行验证。
- 如果用户凭证将在AWS Cognito用户响应的帮助下进行验证,则您将创建有效负载,然后创建JWT令牌。
- 使用公钥-私钥对JWT令牌签名,以便您可以与其他服务共享公钥以验证JWT令牌。
- 然后,JWT令牌返回到前端应用程序。
- 现在,Spring Security将为您保护所有私有路线。
- 您还需要创建一个过滤器,以便当前端应用在标头中附加JWT并向服务器创建ant请求时,您的过滤器将验证JWT令牌(作为身份验证标头),如果该令牌有效,则将创建当前请求的安全上下文,否则抛出401状态。
本文链接:https://www.f2er.com/3068388.html