如何在 Spring Boot & Keycloak 中使用 cookie 和不记名令牌进行身份验证?

时间:2021-03-04 08:46:55

标签: spring-boot cookies spring-security keycloak

我有一个使用 Keycloak 保护的 Spring Boot 应用程序。我试图通过在 cookie 中传递不记名令牌来验证请求。我正在关注 this link 以提取 cookie 中存在的不记名令牌的值并将其设置在 MutableHttpServletRequest 对象上。下面是我的 MutableHttpServletRequestCheckAuthCookieFilter 类。

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 在请求中搜索 customHeadersAuthorization 并使用它?

0 个答案:

没有答案