получить дополнительные атрибуты от jwt при весенней загрузке - PullRequest
0 голосов
/ 17 октября 2019

Я разрабатываю сервис весенней загрузки, который защищен keycloak, и он принимает маркер носителя jwt для аутентификации.

Я также настроил swagger и зарегистрировал его как общедоступный клиент, поэтому, когда я делаю запрос от swagger-ui, keycloak генерирует токен JWT, который swagger затем использует для аутентификации при выполнении запросов к API.

Я также создал 2 дополнительных частных картографа для пользовательской информации. Теперь я хотел бы получить эти 2 атрибута в моем контроллере пружины.

Ниже приведен пример кода.
Я чувствую себя немного потерянным в весенней безопасности и различных способах работы (spring security / oauth2 / keycloak и т. Д.), Поэтому некоторые объяснения этого решения будуточень признателен.

pom.xml

<!-- spring security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <!-- spring security test -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- KeyCloak -->
        <!-- https://mvnrepository.com/artifact/org.keycloak/keycloak-spring-boot-2-starter -->
        <!-- /10661355/keycloak-4-0-0-beta-2-s-spring-boot-2 -->      <!---->
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-spring-boot-2-starter</artifactId>
            <version>4.0.0.Final</version>
        </dependency>

Конфигурация Spring Security

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends KeycloakWebSecurityConfigurerAdapter  {

    @Autowired
    public void configureGlobal(
      AuthenticationManagerBuilder auth) throws Exception {

        KeycloakAuthenticationProvider keycloakAuthenticationProvider
         = keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(
          new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakAuthenticationProvider);
    }

    @Bean
    public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(
          new SessionRegistryImpl());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.authorizeRequests()
          .antMatchers("/test*")
          .hasRole("user")
          .anyRequest()
          .permitAll();
    }



}

пример контроллера

    @RequestMapping(value = "HelloWorld1", method = RequestMethod.GET)
    @ApiOperation(value = "HelloWorld1", produces = "application/json")
    @ResponseBody
    public String HelloWorld1(Principal principal) {
//I'd like something like this to work:
//String attr = principal.getAttribute("attribute1");
//
        System.out.println(principal.getName());
        RestTemplate restTemplate = new RestTemplate();
        String text = restTemplate.getForObject(
            "http://localhost:8080/test/test/HelloWorld", String.class);
        return "Hello " + principal.getName() + " " +  "it works! \n " + text;
    }

1 Ответ

0 голосов
/ 18 октября 2019

Я не знаю для адаптера Keycloak Spring, но вы можете сделать это с помощью модуля Spring Boot для Spring Security OAuth2. В одной из лабораторий Spring I / O 2019 есть хорошее руководство, показывающее 1), как авторизовать на основе некоторого утверждения JWT (или утверждения, полученного из конечной точки UserInfo) в Spring Security DSL;2) как извлечь атрибуты, чтобы использовать их в веб-контроллере, веб-странице и т. Д. См. Раздел «Внедрение клиента».

По сути, вам нужно добавить эту зависимость в ваш проект (пожалуйста, синтаксис Gradleадаптироваться для Maven):

implementation('org.springframework.boot:spring-boot-starter-oauth2-client')

Затем:

Авторизация в Spring Security DSL (HTTP Security) на основе атрибутов / утверждений OIDC

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .anyRequest()
        .fullyAuthenticated()
        .and()
        .oauth2Client()
        .and()
        .oauth2Login()
        .userInfoEndpoint()
        .userAuthoritiesMapper(userAuthoritiesMapper());
  }

  private GrantedAuthoritiesMapper userAuthoritiesMapper() {
    return (authorities) -> {
      Set<GrantedAuthority> mappedAuthorities = new HashSet<>();

      authorities.forEach(
          authority -> {
            if (authority instanceof OidcUserAuthority) {
              OidcUserAuthority oidcUserAuthority = (OidcUserAuthority) authority;

              OidcIdToken idToken = oidcUserAuthority.getIdToken();
              OidcUserInfo userInfo = oidcUserAuthority.getUserInfo();

              List<SimpleGrantedAuthority> groupAuthorities =
                  userInfo.getClaimAsStringList("groups").stream()
                      .map(g -> new SimpleGrantedAuthority("ROLE_" + g.toUpperCase()))
                      .collect(Collectors.toList());
              mappedAuthorities.addAll(groupAuthorities);
            }
          });

      return mappedAuthorities;
    };
  }
}

Использовать утверждения OIDC /атрибуты в веб-контроллере

@GetMapping("/")
  Mono<String> index(@AuthenticationPrincipal OAuth2User oauth2User, Model model) {

    model.addAttribute("fullname", oauth2User.getName());
    model.addAttribute(
        "isCurator",
        ((JSONArray) oauth2User.getAttributes().get("groups")).get(0).equals("library_curator"));
    ...    
}

Источник: https://github.com/andifalk/oidc-workshop-spring-io-2019/tree/master/lab2#implement-the-client

...