【问题标题】:I'm using Cognito + Spring security. There are any way to use authorization?我正在使用 Cognito + Spring 安全性。有什么方法可以使用授权?
【发布时间】:2023-01-13 01:08:33
【问题描述】:

我正在使用 spring Security 和 cognito 进行身份验证和授权。我通过 aws IAM 输入了一些自定义角色,我想知道是否有一种方法可以授予对资源的受控访问权限。在网络上,我发现一些将 cognito:groups 设置为角色并使用了它,但它们使用了已弃用的类和方法。有什么办法可以用最新版本做到这一点吗?

我试图创建一个类:

package com.projectname.name.Configurations;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.lang.NonNull;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;


import java.util.Collection;
import java.util.Collections;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class CognitoAccessTokenConverter implements Converter<Jwt, AbstractAuthenticationToken> {

  private final JwtGrantedAuthoritiesConverter defaultGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();


  public CognitoAccessTokenConverter() {
  }
 
  @Override
  public AbstractAuthenticationToken convert(@NonNull final Jwt jwt) {
      Collection<GrantedAuthority> authorities = Stream
          .concat(defaultGrantedAuthoritiesConverter.convert(jwt).stream(), extractResourceRoles(jwt).stream())
          .collect(Collectors.toSet());           
      return new JwtAuthenticationToken(jwt, authorities);
  }
  
  private static Collection<? extends GrantedAuthority> extractResourceRoles(final Jwt jwt) {
      Collection<String> userRoles = jwt.getClaimAsStringList("cognito:groups");
      //System.out.println("\n!!!!!!!!" +userRoles +"!!!!!!!!!!\n"); DEBUG
      if (userRoles != null)
          return userRoles
                    .stream()
                    .map(role -> new SimpleGrantedAuthority("ROLE_" + role))
                    .collect(Collectors.toSet());
      return Collections.emptySet();
  }
}



 /* 
import java.util.Map;
import java.util.Set;

import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationCode;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationToken;
import org.springframework.stereotype.Component;
import org.springframework.


@Component
public class CognitoAccessTokenConverter extends OAuth2AuthorizationCodeRequestAuthenticationToken{

  
  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";

}


@Component
public class CognitoAccessTokenConverter extends {

  // 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);
  }
} */ 

我如何在我的 spring 安全配置中使用这个转换?

package com.SSDProject.Booked.Configurations;

import java.io.*;

import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.client.endpoint.DefaultRefreshTokenTokenResponseClient;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;


@Configuration
@EnableWebSecurity
public class SecurityConfiguration {    

    @Bean
    SecurityFilterChain web(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize 
                .requestMatchers("/admin").hasAuthority("max")
                .requestMatchers("/**").permitAll()
                .anyRequest().authenticated()
            )
            .oauth2Login();
 

    
                

            return http.build();
    }

帮助我,我试图实现它并到处搜索。有帮助吗?你有想法吗?

【问题讨论】:

    标签: spring spring-security jwt amazon-cognito spring-security-oauth2


    【解决方案1】:

    我最近使用 SpringBoot 2.x 和 Java 17 创建了相同的 PoC。 就我而言,我的 IDE 没有任何弃用警告,这里是我的示例:

      @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf()
                .and()
                .requestMatchers().antMatchers("/api/**")
                .and()
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .userDetailsService(null)
                .oauth2ResourceServer(oauth2 ->
                        oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(grantedAuthoritiesExtractor())));
    
        return http.build();
    }
    
    
    private JwtAuthenticationConverter grantedAuthoritiesExtractor() {
        JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
        jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwt -> {
                    String[] scopes;
                    if (jwt.getClaims().containsKey("cognito:groups")) {
                        scopes = ((JSONArray) jwt.getClaims().get("cognito:groups")).toArray(new String[0]);
                    } else {
                        scopes = ((String) jwt.getClaims().getOrDefault("scope", "")).split(" ");
                    }
                    return Arrays.stream(scopes)
                            .map(role -> new SimpleGrantedAuthority("ROLE_" + role.toUpperCase(Locale.ROOT)))
                            .collect(Collectors.toSet());
                }
    
        );
    
        return jwtAuthenticationConverter;
    }
    

    您的代码中到底弃用了哪一行?您使用的是什么版本的资源服务器?对我来说spring-boot-starter-oauth2-资源服务器是 2.7.5。

    这实际上不是答案,但我没有为问题添加评论的声誉:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-03
      • 2020-10-23
      • 2020-11-29
      • 2017-05-10
      • 2012-04-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多