Информация об аутентификации Spring OAuth2 и JWT

У меня есть приложение Spring Boot (1.3.x), действующее как сервер ресурсов, и я могу передать токен JWT из Keycloak в заголовке авторизации, и мне разрешен доступ к некоторым конечным точкам. Проблема, с которой я сталкиваюсь, заключается в том, что я не могу получить информацию, которая находится в моем токене JWT в объекте авторизации.

SecurityContext sc = SecurityContextHolder.getContext();
Authentication a = sc.getAuthentication(); //OR OAuth2Authentication oa = (OAuth2Authentication)a;
Object p = a.getPrincipal();

и p будет содержать имя client_id, если IDP поместит его в токен.

isClientOnly() возвращает истину. Почему?

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

Я пытался понять, нужно ли мне как-то настраивать то, как обрабатываются токены JWT после проверки, чтобы правильная информация попадала в объект аутентификации, но я полностью запутался. Как я могу это сделать?

Spring Boot великолепен тем, что вы можете сделать так мало, чтобы что-то запустить, но в то же время я не понимаю, с чего начать или что на самом деле вообще установлено...

мое приложение.yml:

server:
  servlet-path: /*

security:
  oauth2:
    resource:
      jwt:
        keyValue:
          -----BEGIN PUBLIC KEY-----
          MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmFbcU2Q6WZwUjEBvsZP8kIiE5mmctTGq1SOrPN5U4MkaTVs/zs2cWf+fhIE4WQ+dF9xTPxrJCGkwCMMXEhReFadOvzW8S3VdKdhng/j2GUbleU1QLSOGLhXu2+ODxeToZGpXIxtJiK2wE0JI9T6UwAe9j/stp4pMUzQubkG9acA+lpA5+zaCylLHysNFlSO1cTgzTdIZpXQGu5nkmyz7xT6vq8n2qAsD5GG5JRpBAac6L10Hnvl1YbwnPfi1T+IZSq7FdSpGJmYeOiPhJF0j7qYOMcaQgOfzoQGBhXslIHZeeaBIuUM6QFgZacJsVxdQoRvMronuuacnS+bngMEVDQIDAQAB
          -----END PUBLIC KEY-----
logging:
  level:
    org:
      springframework:
        security: DEBUG

мой SecurityConfig.java:

package com.something.me;

import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;

@Configuration
@EnableOAuth2Sso
@EnableResourceServer
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {

        //TODO add scope and role restrictions...
        http.authorizeRequests().anyRequest().authenticated();
}

person jeremy simon    schedule 02.02.2016    source источник


Ответы (2)


Возможно, вы запутались с принципом... Насколько я знаю, вы можете ввести его, как и другие бобы... или получить к нему доступ в действии контроллера, подобном этому

@Controller
class MyController {
  @RequestMapping("/greeting") 
  public Principal greeting(Principal user) {
    return user;
  }
}

Кроме того, я не вижу в вашем коде JwtConfiguration, а также компонентов хранилища токенов....

Вы должны настроить что-то вроде этого (при условии, что ваш ключ сохранен в public.cert в вашем каталоге ресурсов)

@Configuration
public class JwtConfiguration {
    @Autowired
    JwtAccessTokenConverter jwtAccessTokenConverter;


    @Bean
    @Qualifier("tokenStore")
    public TokenStore tokenStore() {

        System.out.println("Created JwtTokenStore");
        return new JwtTokenStore(jwtAccessTokenConverter);
    }

    @Bean
    protected JwtAccessTokenConverter jwtTokenEnhancer() {
        JwtAccessTokenConverter converter =  new JwtAccessTokenConverter();
        Resource resource = new ClassPathResource("public.cert");
        String publicKey = null;
        try {
            publicKey = new String(FileCopyUtils.copyToByteArray(resource.getInputStream()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        converter.setVerifierKey(publicKey);
        return converter;
    }
}

Надеюсь, я смог помочь. Возможно, моя статья может дать более подробное объяснение :)

person David Steiman    schedule 07.02.2016

Часть хранилища токенов частично помогла мне... Похоже, моя проблема заключается в том, что я использую Keycloak, и он возвращает токены подключения openid, где имена полей в основном разные. Я жестко закодировал некоторые поля, такие как «user_name» в токене Keycloak, и внезапно смог получить основной объект, хотя и не с большим количеством информации.

Поэтому я ошибался, думая, что материал Spring OAuth2 JWT просто будет автоматически работать с любым JWT. Начало работы с адаптером keycloak.

person jeremy simon    schedule 09.02.2016