Базовая аутентификация Spring boot с использованием токена для RESTAPI

#spring #spring-boot #authentication #access-token

#spring #spring-boot #аутентификация #токен доступа

Вопрос:

Мне нужно предоставить логин пользователя с помощью приложения SpringBoot.

Запрос пользователя на вход в систему будет представлять собой запрос Rest, полезная нагрузка которого состоит из «имени пользователя» и «пароля».

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

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

Даже при первом запросе на вход в систему система будет проверять аутентификацию по токену, которая, очевидно, завершается неудачей.

Я хочу, чтобы система просто сгенерировала токен в первый раз после проверки имени и пароля из базы данных.

Я впервые внедряю вход пользователя в систему с помощью Spring Boot Security, поэтому я довольно невежествен в этом. Хотя я много исследовал и читал онлайн, но все еще не смог разобраться в этой части.

  • Редактировать:

Ниже приведен класс конфигурации безопасности, который расширяет WebSecurityConfigurerAdapter

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

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {

     auth.userDetailsService(userDetailsService)
    .passwordEncoder(getPasswordEncoder());
}



@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable();
    http.authorizeRequests()
    .antMatchers("/","**/firstPage").authenticated()
            .anyRequest().permitAll()
            .and()
            .formLogin().loginPage("/login").
            permitAll()
            .and().logout().permitAll();
}
  

Ниже приведен запрос, который будет вызван после входа в систему.Как аутентифицировать пользователя в нем, используя уже сгенерированный токен? Токен отправляется в заголовке запроса.

  @PostMapping(value = "/home")
public ResponseEntity<ConsolidateResponse> TestReques(@RequestBody TestParam testParam)
        throws Exception {

    //Some logic

   }
  

Комментарии:

1. В принципе, для конечной точки входа в систему вы должны разрешить запрос без авторизации. Это можно сделать в вашем классе конфигурации веб-безопасности, который расширяет WebSecurityConfigurerAdapter

2. Если вы можете добавить свой класс конфигурации веб-безопасности (тот, который расширяется WebSecurityConfigurerAdapter ), я могу указать вам, как вы можете это сделать.

3. @MadhuBhat После отключения аутентификации по умолчанию, как приложение будет проверять подлинность всех запросов, следующих за запросом входа в систему? и как тогда обрабатывать истечение срока действия токена?

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

5. @MadhuBhat Я обновил свой вопрос. Теперь у вас будет более четкая картина. Пожалуйста, дайте мне знать, как аутентифицировать последующие запросы.

Ответ №1:

Если вы отключите форму входа в систему из класса конфигурации spring security и предоставите одну конечную точку rest (/auth), вы сможете обрабатывать вход в систему и генерировать токен.Здесь я использовал jwt для генерации токена.

  @RequestMapping(value = "/auth", method = RequestMethod.POST)
    public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtAuthenticationRequest authenticationRequest) throws AuthenticationException, IOException {
        // Perform the security
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
                authenticationRequest.getUsername(), authenticationRequest.getPassword());

        final Authentication authentication = authManager.authenticate(token);
        if (!authentication.isAuthenticated()) {
            throw new BadCredentialsException("Unknown username or password");
        }

        // Reload password post-security so we can generate token
        final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
        final String jwtoken = jwtTokenUtil.generateToken(userDetails);
        return ResponseEntity.ok(responseBean);
    }
  

При использовании аутентификации без состояния мы можем явно передать параметр token контроллеру и подтвердить его.В случае, если включена аутентификация на основе сеанса, мы также можем использовать @AuthenticationPrincipal for для извлечения текущего зарегистрированного пользователя.

 //Stateless authentication
@PostMapping(value = "/home")
public ResponseEntity<ConsolidateResponse> test(@RequestBody TestParam testParam,String token)
        throws Exception {


    Boolean isValidToken = jwtTokenUtil.validateToken(token);
    if(isValidToken) {
     //Some logic 
    }else {
     //invalid request
    }
}





@PostMapping(value = "/home")
    public ResponseEntity<ConsolidateResponse> test(@RequestBody TestBean requestToken,
            @AuthenticationPrincipal User contextPrincipal, HttpServletRequest req) {

        Optional.ofNullable(contextPrincipal).orElseThrow(InvalidUserSession::new);


        //some logic
    }
  

Комментарии:

1. Будет ли этот метод обрабатывать аутентификацию для последующих запросов и истечение срока действия токена?

2. @Just_another_developer этот метод предназначен для входа в систему и генерации токена. Для проверки истечения срока действия токена или того, что этот пользователь вошел в систему, вы можете просто добавить параметр токена в конечную точку «/ home» и подтвердить токен. Я обновлю свой ответ вкратце

3. спасибо за вашу помощь, у меня есть путаница, хотя, если у кого-то есть этот токен, они могут получить доступ к приложению даже без входа в систему, это правда? допустим, я создаю токен с истечением срока действия в один день, а какие-то хакеры перехватывают запрос и получают токен, теперь они могут получить доступ к приложению, даже не пройдя проверку подлинности. верно?

4. Да, если у кого-то есть действительный токен, то для него будут доступны ресурсы. Вы можете обезопасить трафик с помощью https.