In this tutorial, we will show you, how you can extract the groups of an AWS Cognito user in your Spring Boot application. The OAuth token from AWS Cognito provider encodes the user groups in a field called "cognito:groups". The following example shows you how you can map these groups to Spring Security roles.
Example
This example is a Spring Security configuration that maps the AWS Cognito groups of the logged in user to Spring Security authorities.
1@EnableWebSecurity
2public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
3
4 @Override
5 protected void configure(final HttpSecurity http) throws Exception {
6 http
7 .authorizeRequests(a -> a
8 .anyRequest().authenticated()
9 )
10 .oauth2Login(l -> {
11 l.userInfoEndpoint().userAuthoritiesMapper(userAuthoritiesMapper());
12 }
13 );
14 }
15
16 @Bean
17 public GrantedAuthoritiesMapper userAuthoritiesMapper() {
18 return (authorities) -> {
19 Set<GrantedAuthority> mappedAuthorities = new HashSet<>();
20
21 Optional<OidcUserAuthority> awsAuthority = (Optional<OidcUserAuthority>) authorities.stream()
22 .filter(grantedAuthority -> "ROLE_USER".equals(grantedAuthority.getAuthority()))
23 .findFirst();
24
25 if (awsAuthority.isPresent()) {
26 mappedAuthorities = ((JSONArray) awsAuthority.get().getAttributes().get("cognito:groups")).stream()
27 .map(role -> new SimpleGrantedAuthority("ROLE_" + role))
28 .collect(Collectors.toSet());
29 }
30
31 return mappedAuthorities;
32 };
33 }
34}
35
The authority
with the name "USER_ROLE"
is the OpenID Connect Token, which holds all the information about the user provided by AWS Cognito.
Once we have the OpenID token we extract the AWS Cognito groups from the property "cognito:groups"
. The value is a JSONArray that holds all groups of the user.
We can now extract these groups and map them to SimpleGrantedAuthority
roles, which Spring Security understands.
Annotating controllers with Spring Security annotations
Now that we have mapped our AWS Cognito groups into a format that our Spring Security context can understand, we can annotate our controllers with the well known Spring Security annotations.
1@RestController
2public class CommentController {
3
4 @PreAuthorize("hasRole('COMMENTER')")
5 @GetMapping("/comments")
6 public String getComments() {
7 return "comments";
8 }
9
10 @PreAuthorize("hasRole('MODERATOR')")
11 @DELETE("/comments")
12 public void deleteComments() {
13 // delete comments
14 }
15}
16
Conclusion
We can easily map the groups from the AWS Cognito user to Spring Security authorities with just a few lines of code and then make use of the large ecosystem provided by Spring to secure our application.