我试图找出有关我创建的用于获取用户令牌信息并将其登录到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
并每次都工作?