#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 в фильтре не работает, было бы неплохо узнать.