Я пытаюсь выяснить проблему с фильтром, который я создал, чтобы получить информацию о токене пользователя и зарегистрировать их на MDC (чтобы отобразить информацию о пользователе в Graylog).
MdcRequestFilter
вызывает UserService
, который отвечает за получение информации о токене.Код UserService
выглядит следующим образом:
@Slf4j
@AllArgsConstructor
@Service
public class UserService {
private final OAuth2ClientContext context;
public Optional<User> getUser() {
OAuth2AccessToken oAuth2AccessToken = context.getAccessToken();
if (oAuth2AccessToken == null) {
return Optional.empty();
}
String token = oAuth2AccessToken.getValue();
// ... code
}
}
Я заметил, что oAuth2AccessToken
равен нулю иногда , что очень странно.Это происходит не во всех запросах.
Если я использую другую реализацию для получения токена, используя SecurityContextHolder.getContext().getAuthentication()
, токен всегда доступен:
@Slf4j
@Service
public class UserService {
public Optional<User> getUser() {
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication instanceof AnonymousAuthenticationToken) {
return Optional.empty();
}
final String token = ((OAuth2AuthenticationDetails) authentication.getDetails()).getTokenValue();
// code
}
}
Реализация фильтра:
@Aspect
@Component
@Slf4j
public class MdcRequestFilter implements Filter {
private static final String USERNAME = "username";
private static final String COMPANY = "company";
@Autowired
private UserService userService;
@Override
public void init(final FilterConfig filterConfig) {
}
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
Optional<User> optionalUser = userService.getUser();
try {
if (optionalUser.isPresent()) {
User user = optionalUser.get();
MDC.put(USERNAME, user.getUsername());
MDC.put(COMPANY, Objects.toString(user.getCompany()));
}
} catch (Exception ex) {
log.debug("Error on MDC", ex);
}
chain.doFilter(request, response);
MDC.remove(USERNAME);
MDC.remove(COMPANY);
}
@Override
public void destroy() {
}
}
Итак, я подозреваю, что OAuth2ClientContext
не заполняется информацией о токене при вызове фильтра, некоторые проблемы связаны с приоритетом между ними.Это имеет смысл?Если да, есть ли способ использовать OAuth2ClientContext
внутри фильтра и работать каждый раз?