@Override
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
      throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    _log.debug(
        "{} {}, contentlength: {}",
        request.getMethod(),
        request.getRequestURI(),
        Integer.valueOf(request.getContentLength()));

    AuthorizationHeader authorizationHeader = new AuthorizationHeader(request);

    // authenticate user
    if (!authorizationHeader.isNull()
        && _provider.isSecurityPackageSupported(authorizationHeader.getSecurityPackage())) {

      // log the user in using the token
      IWindowsIdentity windowsIdentity = null;

      try {
        windowsIdentity = _provider.doFilter(request, response);
        if (windowsIdentity == null) {
          return;
        }
      } catch (IOException e) {
        _log.warn("error logging in user: {}", e.getMessage());
        _log.trace("{}", e);
        sendUnauthorized(response, true);
        return;
      }

      if (!_allowGuestLogin && windowsIdentity.isGuest()) {
        _log.warn("guest login disabled: {}", windowsIdentity.getFqn());
        sendUnauthorized(response, true);
        return;
      }

      try {
        _log.debug(
            "logged in user: {} ({})", windowsIdentity.getFqn(), windowsIdentity.getSidString());

        WindowsPrincipal principal =
            new WindowsPrincipal(windowsIdentity, _principalFormat, _roleFormat);

        _log.debug("roles: {}", principal.getRolesString());

        Authentication authentication =
            new WindowsAuthenticationToken(
                principal, _grantedAuthorityFactory, _defaultGrantedAuthority);

        SecurityContextHolder.getContext().setAuthentication(authentication);

        _log.info("successfully logged in user: {}", windowsIdentity.getFqn());

      } finally {
        windowsIdentity.dispose();
      }
    }

    chain.doFilter(request, response);
  }