我有一个使用 Keycloak 保护的 Spring Boot 应用程序。我试图通过在 cookie 中传递不记名令牌来验证请求。我正在关注 this link 以提取 cookie 中存在的不记名令牌的值并将其设置在 MutableHttpServletRequest
对象上。下面是我的 MutableHttpServletRequest
和 CheckAuthCookieFilter
类。
public class MutableHttpServletRequest extends HttpServletRequestWrapper {
private final Map<String, String> customHeaders;
/**
* Constructs a request object wrapping the given request.
*
* @param request the {@link HttpServletRequest} to be wrapped.
* @throws IllegalArgumentException if the request is null
*/
public MutableHttpServletRequest(HttpServletRequest request) {
super(request);
this.customHeaders = new HashMap<>();
}
public void putHeader(String name, String value) {
this.customHeaders.put(name, value);
}
public String getHeader(String name) {
String headerValue = customHeaders.get(name);
if (headerValue != null) {
return headerValue;
}
return ((HttpServletRequest) getRequest()).getHeader(name);
}
public Enumeration<String> getHeaderNames() {
Set<String> set = new HashSet<String>(customHeaders.keySet());
Enumeration<String> e = ((HttpServletRequest) getRequest()).getHeaderNames();
while (e.hasMoreElements()) {
String n = e.nextElement();
set.add(n);
}
return Collections.enumeration(set);
}
}
@Slf4j
public class CheckAuthCookieFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.info("INSIDE CheckAuthCookieFilter");
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(httpServletRequest);
Cookie[] cookies = httpServletRequest.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
log.debug(cookie.getName() + " : " + cookie.getValue());
if (cookie.getName().equalsIgnoreCase("auth")) {
mutableRequest.putHeader("Authorization", cookie.getValue());
}
}
}
chain.doFilter(mutableRequest, response);
}
}
以下是我的过滤器链。
Security filter chain: [
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
CheckAuthCookieFilter
HeaderWriterFilter
KeycloakPreAuthActionsFilter
KeycloakAuthenticationProcessingFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
KeycloakSecurityContextRequestFilter
KeycloakAuthenticatedActionsFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
当 Keycloak 尝试对该请求进行身份验证时,它正在获取一个 MutableHttpServletRequest
实例,我可以看到 customHeaders
字段中存在授权标头。但是,Keycloak 无法验证此请求并最终抛出带有 KeycloakAuthenticationException("Authorization header not found, see WWW-Authenticate header")
的 401。此异常是从 KeycloakAuthenticationProcessingFilter
类抛出的。
如何确保 KeycloakAuthenticationProcessingFilter
在请求中搜索 customHeaders
的 Authorization
并使用它?