Ошибка при доступе к JPA внутри аутентификации безопасности Spring Boot

#spring #spring-boot #jpa #spring-security

#spring #spring-boot #jpa #spring-безопасность

Вопрос:

Я реализую API REST с Spring Boot, следуя некоторым руководствам в Интернете, все в порядке, пока мне не понадобится использовать токен обновления для восстановления токена аутентификации после истечения срока его действия. Итак, в моей системе безопасности Spring Boot я добавил экземпляр refreshToken с идентификатором пользователя.

 @Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
                                        Authentication auth) throws IOException, ServletException {

    String token = Jwts.builder().setIssuedAt(new Date()).setIssuer(ISSUER_INFO)
            .setSubject(((org.springframework.security.core.userdetails.User) auth.getPrincipal()).getUsername())
            .setExpiration(new Date(System.currentTimeMillis()   TOKEN_EXPIRATION_TIME))
            .signWith(SignatureAlgorithm.HS512, SUPER_SECRET_KEY).compact();

    String refreshTokenString = UUID.randomUUID().toString();
    RefreshToken refreshToken = new RefreshToken(refreshTokenString, Long.parseLong(StringUtils.substringAfter(((org.springframework.security.core.userdetails.User) auth.getPrincipal()).getUsername(), Constants.STRING_SEPARATOR4)));
    refreshTokenRepository.save(refreshToken);   <-------------------------------------- ERROR HERE!!!!

    response.addHeader(HEADER_AUTHORIZACION_KEY, TOKEN_BEARER_PREFIX   " "   token);

    response.addHeader("refreshToken", refreshTokenString);

    response.addHeader("emailHash",
            StringUtils.substringBetween(((org.springframework.security.core.userdetails.User) auth.getPrincipal()).getUsername(), Constants.STRING_SEPARATOR1, Constants.STRING_SEPARATOR2)
    );
    response.addHeader("instanceId",
            StringUtils.substringBetween(((org.springframework.security.core.userdetails.User) auth.getPrincipal()).getUsername(), Constants.STRING_SEPARATOR2, Constants.STRING_SEPARATOR3)
    );
    response.addHeader("enabled",
            StringUtils.substringBetween(((org.springframework.security.core.userdetails.User) auth.getPrincipal()).getUsername(), Constants.STRING_SEPARATOR3, Constants.STRING_SEPARATOR4)
    );
}
 

Ошибка, которую я всегда получаю, находится в строке .save() репозитория.

 2020-11-19T17:19:09.613116 00:00 app[web.1]: 2020-11-19 17:19:09.612 ERROR 4 --- [io-56866-exec-4] o.s.b.w.servlet.support.ErrorPageFilter  : Forwarding to error page from request [/login] due to exception [null]
2020-11-19T17:19:09.613127 00:00 app[web.1]:
2020-11-19T17:19:09.613127 00:00 app[web.1]: java.lang.NullPointerException: null
 

Раньше я пытался получить полный экземпляр пользователя из JPA и получал ту же ошибку при выполнении findByEmail, которую я использую во всем приложении без каких-либо проблем, поэтому я думаю, что это что-то связанное с сохранением, но я потерялся, без этого .save(), все остальное работает нормально, за исключением того, чтотокен обновления не сохраняется: (

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

1. Мне кажется, что это проблема с внедрением компонентов. Как вы создаете экземпляр репозитория здесь? А также, как вы создаете экземпляр самого SecurityConfig? Если вы используете автозапуск, убедитесь, что используете его последовательно.

2. Вау, это правда … решена! Я публикую ответ… Спасибо!

Ответ №1:

Найдено решение! Проблема была в экземпляре репозитория, я сделал это в фильтре, используя:

 @Autowired
private RefreshTokenRepository refreshTokenRepository;
 

Я не понимаю почему, но я так не работаю, поэтому я переместил экземпляр в класс конфигурации безопасности и передал переменную репозитория в качестве параметра в фильтр, тогда это сработало! Спасибо k-wasilewski.

Если кто-нибудь знает, почему экземпляр с @Autowired в фильтре не работает, было бы неплохо узнать.