Реализация типа предоставления кода авторизации потока OAuth2 - PullRequest
0 голосов
/ 24 мая 2018

У меня настоящая проблема, и мне нужна ваша помощь.Я работаю в банке, и мне было поручено внедрить службу OAuth2 с помощью Spring Boot, я изучал ее с прошлой недели и смог внедрить службу OAuth2 типа предоставления потока паролей, но теперь у меня есть несколько вопросов:мои старшие сказали, что поток паролей не подходит для нашего варианта использования.Сначала я хотел бы объяснить пример использования:

Шаг 1: пользователь нажимает URL-адрес приложения веб-приложения, для которого не требуется вход в систему, и перед загрузкой приложения служба OAuth2 получит вход в AD (system) user id.

Шаг 2. Служба OAuth2 должна аутентифицировать пользователя с использованием ldap с заданным идентификатором пользователя и вернуть обратно все группы, в которые входит пользователь, вместе с токеном доступа, который будет использоваться для доступа кAPI там после

Теперь у меня есть следующие запросы:

  1. Какой тип гранта лучше всего подходит для моих нужд, из того, что я прочитал, код авторизации, похоже, тип грантаправильная посадка?Или это неявно?

  2. В зависимости от ответа на вопрос 1, какие изменения кода мне необходимо внести в приведенный ниже код:

Кодфрагмент моего сервера авторизации:

Oauth2AuthserverApplication.java

     @SpringBootApplication
     @EnableAuthorizationServer
     public class Oauth2AuthserverApplication {

     public static void main(String[] args) {
          SpringApplication.run(Oauth2AuthserverApplication.class, args);
     }
  }

OAuth2Congig.java

   @Configuration
   public class Oauth2Config extends AuthorizationServerConfigurerAdapter {

   private String clientId = "client";
   private String clientSecret = "secret";
   private String privateKey = "private-key";
   private String publicKey = "public-key";


  @Autowired
  @Qualifier("authenticationManagerBean")
  private AuthenticationManager authenticationManager;

  @Bean
  public JwtAccessTokenConverter tokenEnhancer() {
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    converter.setSigningKey(privateKey);
    converter.setVerifierKey(publicKey);
    return converter;
  }

  @Bean
  public JwtTokenStore tokenStore() {
    return new JwtTokenStore(tokenEnhancer());
  }

  @Override
  public void configure(AuthorizationServerEndpointsConfigurer endpoints) 
             throws Exception {
          endpoints.authenticationManager(authenticationManager).
              tokenStore(tokenStore())
                  .accessTokenConverter(tokenEnhancer());
  }

  @Override
  public void configure(AuthorizationServerSecurityConfigurer security) 
                 throws Exception {
          security.tokenKeyAccess("permitAll()").
              checkTokenAccess("isAuthenticated()");
  }

  @Override
  public void configure(ClientDetailsServiceConfigurer clients) throws 
               Exception {

     clients.inMemory().withClient(clientId).
           secret(clientSecret).scopes("read", "write")
            .authorizedGrantTypes("password", 
                 "refresh_token").accessTokenValiditySeconds(20000)
            .refreshTokenValiditySeconds(20000);

     }

  }

SecurityConfiguration.java

   @Configuration
   @EnableWebSecurity
   @EnableGlobalMethodSecurity(prePostEnabled = true)
   public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

   @Autowired
   CustomDetailsService customDetailsService;

   @Bean
   public PasswordEncoder encoder() {
    return new BCryptPasswordEncoder();
   }

   @Override
   @Autowired
   protected void configure(AuthenticationManagerBuilder auth) throws 
              Exception {
          auth.userDetailsService(customDetailsService).
                    passwordEncoder(encoder());
   }

   @Override
   protected void configure(HttpSecurity http) throws Exception {
             http.authorizeRequests().anyRequest().authenticated().
                  and().sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
   }

   @Override
   @Bean
   public AuthenticationManager authenticationManagerBean() throws Exception 
       {
           return super.authenticationManagerBean();
   }
 }

Не вставлятьмодель, дао и сервисный код класса сервера авторизации, поскольку они не относятся к данному вопросу.

Фрагмент кода из проекта сервера ресурсов:

OAuth2ResourceserverApplication.java

   @SpringBootApplication
   @EnableResourceServer
   @RestController
   public class Oauth2ResourceserverApplication {

      public static void main(String[] args) {
         SpringApplication.run(Oauth2ResourceserverApplication.class, args);
      }


     @RequestMapping(value="/api")
     public String success() {
         return "SUCCESS";
     }
  }

JwtConverter.java

  @Component
  public class JwtConverter extends DefaultAccessTokenConverter implements 
           JwtAccessTokenConverterConfigurer {

     @Override
     public void configure(JwtAccessTokenConverter converter) {
              converter.setAccessTokenConverter(this);
     }
  }

SecurityConfiguration.java

   @Configuration
   @EnableWebSecurity
   @EnableGlobalMethodSecurity(prePostEnabled = true)
   public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

   @Override
   protected void configure(HttpSecurity http) throws Exception {
     http.authorizeRequests().anyRequest().authenticated().
                  and().sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.NEVER);
   }
 }

application.yml

 server:
 port: 8081
 security:
 oauth2:
    resource:
        filter-order: 3 
        jwt: 
            key-value: private-key

1 Ответ

0 голосов
/ 07 августа 2018

OAuth2 имеет 4 типа предоставления.Чтобы быстро понять разницу между «Учетными данными пароля владельца ресурса», «Кодом авторизации», «Неявным», давайте сравним их бок о бок:

OAuth2 grant types introduction and comparison

ПРИМЕЧАНИЕ: Полное объяснение доступно по адресу: https://blog.oauth.io/oauth2-flow-grant-types-in-pictures/.

Чтобы ответить на ваш вопрос:

  1. Какой тип гранта лучше всего подходит для моих нужд, из того, что я прочитал тип разрешения кода авторизации, кажется, подходит?Или это неявно?

Если сравнивать на основе «Безопасность» фиолетовую полосу, то «Код авторизации» лучше всего.Однако вы можете видеть, что у него есть концепция Guard (бэкэнд), которая осуществляет доступ к хранилищу данных пользователя от имени приложения (веб-интерфейс), т. Е. Приложение никогда не имеет доступа к ключу / токену доступа напрямую,поскольку ключ извлекается путем обмена именем пользователя / паролем между пользователем и сервером OAuth, а затем передается гвардии.

Реализованные вами «учетные данные пароля владельца ресурса» наименее безопасны, так какимя пользователя / пароль передается в приложение для приложения, чтобы делать все, что может пользователь без его согласия.Однако в вашем сценарии приложение и хранилище пользовательских данных принадлежат вам, что устраняет проблему безопасности.

В зависимости от ответа на вопрос 1, какие изменения кода мне нужно внести в приведенный ниже код:

Полный поток реализованного вами типа предоставления учетных данных пароля владельца ресурса является левой частьюизображение ниже и тип предоставления кода авторизации является правой частью.Как видите, обычно есть 5 шагов.Для учетных данных владельца ресурса некоторые шаги не требуются, т. Е. Отмечены как «NA».

Resource Owner Password Credential and Authorization Code full flow comparison

ПРИМЕЧАНИЕ:

  • «Облако» представляет приложение
  • «www» представляет пользователя / браузер
  • «Сейф» представляет OAuth-сервер

Чтобы перейти с левой стороны на правую, вам потребуются следующие изменения:

Шаг 1. Если ваш сервер OAuth будет поддерживать разные приложения, то он должен поддерживать предварительную регистрацию приложений.получить идентификатор клиента / секрет.Если у вас есть только одно приложение, вы можете пропустить это.

Шаг 2. Вместо того, чтобы приложение запрашивало имя пользователя / пароль, теперь приложение будет перенаправлять пользователя на сервер OAuth для выполнения аутентификации по имени / паролю

Шаг 3. После аутентификации Пользователя OAuth-сервер может запросить Пользователя о том, какие разрешения (например, чтение электронной почты, обновление профиля и т. Д.) Он хочет предоставить Приложению

Шаг 4.Сервер OAuth вместо передачи токена ключа / доступа в приложение передает код пользователю, который затем передает его приложению

Шаг 5. Затем приложение обменивается кодом для токена ключа / доступа сOAuth Server.

Получив ключ / токен доступа, вы можете вызвать любой защищенный API на другом сервере, который затем может проверить ключ / доступ токена на сервере OAuth перед ответом на запрос API, например, вернутьгруппы, к которым принадлежит пользователь.

...