@SuppressWarnings({"ThrowableInstanceNeverThrown"})
 private void useAnonymousIfPossible(
     HttpServletRequest request,
     HttpServletResponse response,
     FilterChain chain,
     SecurityContext securityContext)
     throws IOException, ServletException {
   boolean anonAccessEnabled = context.getAuthorizationService().isAnonAccessEnabled();
   if (anonAccessEnabled || authInterceptors.accept(request)) {
     log.debug("Using anonymous");
     Authentication authentication = getNonUiCachedAuthentication(request);
     if (authentication == null) {
       log.debug("Creating the Anonymous token");
       final UsernamePasswordAuthenticationToken authRequest =
           new UsernamePasswordAuthenticationToken(UserInfo.ANONYMOUS, "");
       AuthenticationDetailsSource ads = new HttpAuthenticationDetailsSource();
       //noinspection unchecked
       authRequest.setDetails(ads.buildDetails(request));
       // explicitly ask for the default spring authentication manager by name (we have another one
       // which
       // is only used by the basic authentication filter)
       AuthenticationManager authenticationManager =
           context.beanForType("authenticationManager", AuthenticationManager.class);
       authentication = authenticationManager.authenticate(authRequest);
       if (authentication != null
           && authentication.isAuthenticated()
           && !RequestUtils.isUiRequest(request)) {
         AuthCacheKey authCacheKey =
             new AuthCacheKey(authFilter.getCacheKey(request), request.getRemoteAddr());
         nonUiAuthCache.put(authCacheKey, authentication);
         log.debug("Added anonymous authentication {} to cache", authentication);
       }
     } else {
       log.debug("Using cached anonymous authentication");
     }
     useAuthentication(request, response, chain, authentication, securityContext);
   } else {
     if (authFilter.acceptEntry(request)) {
       log.debug("Sending request requiring authentication");
       authFilter.commence(
           request,
           response,
           new InsufficientAuthenticationException("Authentication is required"));
     } else {
       log.debug("No filter or entry just chain");
       chain.doFilter(request, response);
     }
   }
 }
 private Authentication getNonUiCachedAuthentication(HttpServletRequest request) {
   // return cached authentication only if this is a non ui request (this guards the case when user
   // accessed
   // Artifactory both from external tool and from the ui)
   AuthCacheKey authCacheKey =
       new AuthCacheKey(authFilter.getCacheKey(request), request.getRemoteAddr());
   return RequestUtils.isUiRequest(request) ? null : nonUiAuthCache.get(authCacheKey);
 }
 private void authenticateAndExecute(
     HttpServletRequest request,
     HttpServletResponse response,
     FilterChain chain,
     SecurityContext securityContext)
     throws IOException, ServletException {
   // Try to see if authentication in cache based on the hashed header and client ip
   Authentication authentication = getNonUiCachedAuthentication(request);
   if (authentication != null
       && authentication.isAuthenticated()
       && !reAuthenticationRequired(request, authentication)) {
     log.debug("Header authentication {} found in cache.", authentication);
     useAuthentication(request, response, chain, authentication, securityContext);
     // Add to user change cache the login state
     addToUserChange(authentication);
     return;
   }
   try {
     authFilter.doFilter(request, response, chain);
   } finally {
     Authentication newAuthentication = securityContext.getAuthentication();
     if (newAuthentication != null && newAuthentication.isAuthenticated()) {
       // Add to user change cache the login state
       addToUserChange(newAuthentication);
       // Save authentication like in Wicket Session (if session exists)
       if (RequestUtils.setAuthentication(request, newAuthentication, false)) {
         log.debug("Added authentication {} in Http session.", newAuthentication);
       } else {
         // If it did not work use the header cache
         // An authorization cache key with no header can only be used for Anonymous authentication
         AuthCacheKey authCacheKey =
             new AuthCacheKey(authFilter.getCacheKey(request), request.getRemoteAddr());
         String username = newAuthentication.getName();
         if ((UserInfo.ANONYMOUS.equals(username) && authCacheKey.hasEmptyHeader())
             || (!UserInfo.ANONYMOUS.equals(username) && !authCacheKey.hasEmptyHeader())) {
           nonUiAuthCache.put(authCacheKey, newAuthentication);
           userChangedCache.get(username).addAuthCacheKey(authCacheKey);
           log.debug("Added authentication {} in cache.", newAuthentication);
         }
       }
     }
     securityContext.setAuthentication(null);
   }
 }
 @Override
 public void initLater(FilterConfig filterConfig) throws ServletException {
   ServletContext servletContext = filterConfig.getServletContext();
   this.context = RequestUtils.getArtifactoryContext(servletContext);
   ArtifactoryAuthenticationFilterChain filterChain = new ArtifactoryAuthenticationFilterChain();
   // Add all the authentication filters
   // TODO: [by yl] Support ordering...
   filterChain.addFilters(context.beansForType(ArtifactoryAuthenticationFilter.class).values());
   authFilter = filterChain;
   initCaches(filterConfig);
   authFilter.init(filterConfig);
   authInterceptors = new AnonymousAuthenticationInterceptors();
   authInterceptors.addInterceptors(
       context.beansForType(AnonymousAuthenticationInterceptor.class).values());
 }
 private boolean reAuthenticationRequired(
     HttpServletRequest request, Authentication authentication) {
   if (authentication == null || !authentication.isAuthenticated()) {
     // Not authenticated so not required to redo ;-)
     return false;
   }
   // If user changed force re-auth
   String username = authentication.getName();
   AuthenticationCache authenticationCache = userChangedCache.get(username);
   if (authenticationCache != null && authenticationCache.isChanged(authentication)) {
     authenticationCache.loggedOut(authentication);
     return true;
   }
   return authFilter.requiresReAuthentication(request, authentication);
 }
 @Override
 public void destroy() {
   // May not be inited yet
   if (authFilter != null) {
     authFilter.destroy();
   }
   if (nonUiAuthCache != null) {
     nonUiAuthCache.clear();
     nonUiAuthCache = null;
   }
   if (userChangedCache != null) {
     userChangedCache.clear();
     userChangedCache = null;
   }
 }
 private void doFilterInternal(
     HttpServletRequest request, HttpServletResponse response, FilterChain chain)
     throws IOException, ServletException {
   final String servletPath = RequestUtils.getServletPathFromRequest(request);
   // add no cache header to web app request
   RequestUtils.addNoCacheToWebAppRequest(servletPath, response);
   String method = request.getMethod();
   if ((servletPath == null || "/".equals(servletPath) || servletPath.length() == 0)
       && "get".equalsIgnoreCase(method)) {
     // We were called with an empty path - redirect to the app main page
     response.sendRedirect(HttpUtils.ANGULAR_WEBAPP + "/");
     return;
   }
   // Reuse the authentication if it exists
   Authentication authentication = RequestUtils.getAuthentication(request);
   boolean isAuthenticated = authentication != null && authentication.isAuthenticated();
   // Make sure this is called only once
   boolean reAuthRequired = reAuthenticationRequired(request, authentication);
   if (reAuthRequired) {
     /**
      * A re-authentication is required but we might still have data that needs to be invalidated
      * (like the Wicket session)
      */
     Map<String, LogoutHandler> logoutHandlers =
         ContextHelper.get().beansForType(LogoutHandler.class);
     for (LogoutHandler logoutHandler : logoutHandlers.values()) {
       logoutHandler.logout(request, response, authentication);
     }
   }
   boolean authenticationRequired = !isAuthenticated || reAuthRequired;
   SecurityContext securityContext = SecurityContextHolder.getContext();
   if (authenticationRequired) {
     if (authFilter.acceptFilter(request)) {
       authenticateAndExecute(request, response, chain, securityContext);
     } else {
       useAnonymousIfPossible(request, response, chain, securityContext);
     }
   } else {
     log.debug("Using authentication {} from Http session.", authentication);
     useAuthentication(request, response, chain, authentication, securityContext);
   }
 }