All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.solr.security.AuthenticationPlugin Maven / Gradle / Ivy

There is a newer version: 9.7.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.solr.security;

import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import com.codahale.metrics.Counter;
import com.codahale.metrics.Meter;
import com.codahale.metrics.Timer;
import org.apache.http.HttpRequest;
import org.apache.http.protocol.HttpContext;
import org.apache.solr.core.SolrInfoBean;
import org.apache.solr.metrics.SolrMetricProducer;
import org.apache.solr.metrics.SolrMetricsContext;
import org.eclipse.jetty.client.api.Request;

/**
 * 
 * @lucene.experimental
 */
public abstract class AuthenticationPlugin implements SolrInfoBean, SolrMetricProducer {

  final public static String AUTHENTICATION_PLUGIN_PROP = "authenticationPlugin";
  final public static String HTTP_HEADER_X_SOLR_AUTHDATA = "X-Solr-AuthData";

  // Metrics
  private Set metricNames = ConcurrentHashMap.newKeySet();
  protected SolrMetricsContext solrMetricsContext;

  protected Meter numErrors = new Meter();
  protected Counter requests = new Counter();
  protected Timer requestTimes = new Timer();
  protected Counter totalTime = new Counter();
  protected Counter numAuthenticated = new Counter();
  protected Counter numPassThrough = new Counter();
  protected Counter numWrongCredentials = new Counter();
  protected Counter numMissingCredentials = new Counter();

  /**
   * This is called upon loading up of a plugin, used for setting it up.
   * @param pluginConfig Config parameters, possibly from a ZK source
   */
  public abstract void init(Map pluginConfig);

  /**
   * This method attempts to authenticate the request. Upon a successful authentication, this
   * must call the next filter in the filter chain and set the user principal of the request,
   * or else, upon an error or an authentication failure, throw an exception.
   *
   * @param request the http request
   * @param response the http response
   * @param filterChain the servlet filter chain
   * @return false if the request not be processed by Solr (not continue), i.e.
   * the response and status code have already been sent.
   * @throws Exception any exception thrown during the authentication, e.g. PrivilegedActionException
   */
  //TODO redeclare params as HttpServletRequest & HttpServletResponse
  public abstract boolean doAuthenticate(ServletRequest request, ServletResponse response,
      FilterChain filterChain) throws Exception;

  /**
   * This method is called by SolrDispatchFilter in order to initiate authentication.
   * It does some standard metrics counting.
   */
  public final boolean authenticate(ServletRequest request, ServletResponse response, FilterChain filterChain) throws Exception {
    Timer.Context timer = requestTimes.time();
    requests.inc();
    try {
      return doAuthenticate(request, response, filterChain);
    } catch(Exception e) {
      numErrors.mark();
      throw e;
    } finally {
      long elapsed = timer.stop();
      totalTime.inc(elapsed);
    }
  }

  /**
   * Override this method to intercept internode requests. This allows your authentication
   * plugin to decide on per-request basis whether it should handle inter-node requests or
   * delegate to {@link PKIAuthenticationPlugin}. Return true to indicate that your plugin
   * did handle the request, or false to signal that PKI plugin should handle it. This method
   * will be called by {@link PKIAuthenticationPlugin}'s interceptor.
   *
   * 

* If not overridden, this method will return true for plugins implementing {@link HttpClientBuilderPlugin}. * This method can be overridden by subclasses e.g. to set HTTP headers, even if you don't use a clientBuilder. *

* @param httpRequest the httpRequest that is about to be sent to another internal Solr node * @param httpContext the context of that request. * @return true if this plugin handled authentication for the request, else false */ protected boolean interceptInternodeRequest(HttpRequest httpRequest, HttpContext httpContext) { return this instanceof HttpClientBuilderPlugin; } /** * Override this method to intercept internode requests. This allows your authentication * plugin to decide on per-request basis whether it should handle inter-node requests or * delegate to {@link PKIAuthenticationPlugin}. Return true to indicate that your plugin * did handle the request, or false to signal that PKI plugin should handle it. This method * will be called by {@link PKIAuthenticationPlugin}'s interceptor. * *

* If not overridden, this method will return true for plugins implementing {@link HttpClientBuilderPlugin}. * This method can be overridden by subclasses e.g. to set HTTP headers, even if you don't use a clientBuilder. *

* @param request the httpRequest that is about to be sent to another internal Solr node * @return true if this plugin handled authentication for the request, else false */ protected boolean interceptInternodeRequest(Request request) { return this instanceof HttpClientBuilderPlugin; } /** * Cleanup any per request data */ public void closeRequest() { } @Override public SolrMetricsContext getSolrMetricsContext() { return solrMetricsContext; } @Override public void initializeMetrics(SolrMetricsContext parentContext, String scope) { this.solrMetricsContext = parentContext.getChildContext(this); // Metrics numErrors = this.solrMetricsContext.meter(this, "errors", getCategory().toString(), scope); requests = this.solrMetricsContext.counter(this, "requests", getCategory().toString(), scope); numAuthenticated = this.solrMetricsContext.counter(this, "authenticated",getCategory().toString(), scope); numPassThrough = this.solrMetricsContext.counter(this, "passThrough", getCategory().toString(), scope); numWrongCredentials = this.solrMetricsContext.counter(this, "failWrongCredentials",getCategory().toString(), scope); numMissingCredentials = this.solrMetricsContext.counter(this, "failMissingCredentials",getCategory().toString(), scope); requestTimes = this.solrMetricsContext.timer(this,"requestTimes", getCategory().toString(), scope); totalTime = this.solrMetricsContext.counter(this,"totalTime", getCategory().toString(), scope); } @Override public String getName() { return this.getClass().getName(); } @Override public String getDescription() { return "Authentication Plugin " + this.getClass().getName(); } @Override public Category getCategory() { return Category.SECURITY; } @Override public Set getMetricNames() { return metricNames; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy