SOLR-7896: Avoid browser basicAuth dialogue when blockUnknown=false. Always show Dashboard menu. Clarify refGuide

This commit is contained in:
Jan Høydahl 2019-01-07 13:02:44 +01:00
parent 2bd6f246b0
commit 0b6ea3f108
3 changed files with 23 additions and 16 deletions

View File

@ -29,6 +29,7 @@ import java.io.UnsupportedEncodingException;
import java.lang.invoke.MethodHandles;
import java.nio.charset.StandardCharsets;
import java.security.Principal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -118,18 +119,7 @@ public class BasicAuthPlugin extends AuthenticationPlugin implements ConfigEdita
}
private void authenticationFailure(HttpServletResponse response, boolean isAjaxRequest, String message) throws IOException {
for (Map.Entry<String, String> entry : authenticationProvider.getPromptHeaders().entrySet()) {
String value = entry.getValue();
// Prevent browser from intercepting basic authentication header when reqeust from Admin UI
if (isAjaxRequest && HttpHeaders.WWW_AUTHENTICATE.equalsIgnoreCase(entry.getKey()) && value != null) {
if (value.startsWith("Basic ")) {
value = "x" + value;
log.debug("Prefixing {} header for Basic Auth with 'x' to prevent browser basic auth popup",
HttpHeaders.WWW_AUTHENTICATE);
}
}
response.setHeader(entry.getKey(), value);
}
getPromptHeaders(isAjaxRequest).forEach(response::setHeader);
response.sendError(401, message);
}
@ -195,12 +185,29 @@ public class BasicAuthPlugin extends AuthenticationPlugin implements ConfigEdita
return false;
} else {
numPassThrough.inc();
request.setAttribute(AuthenticationPlugin.class.getName(), authenticationProvider.getPromptHeaders());
request.setAttribute(AuthenticationPlugin.class.getName(), getPromptHeaders(isAjaxRequest));
filterChain.doFilter(request, response);
return true;
}
}
/**
* Get the prompt headers, and replace Basic with xBasic if ajax request to avoid
* browser intercepting the authentication
* @param isAjaxRequest set to true if the request is an ajax request
* @return map of headers
*/
private Map<String, String> getPromptHeaders(boolean isAjaxRequest) {
Map<String,String> headers = new HashMap(authenticationProvider.getPromptHeaders());
if (isAjaxRequest && headers.containsKey(HttpHeaders.WWW_AUTHENTICATE)
&& headers.get(HttpHeaders.WWW_AUTHENTICATE).startsWith("Basic ")) {
headers.put(HttpHeaders.WWW_AUTHENTICATE, "x" + headers.get(HttpHeaders.WWW_AUTHENTICATE));
log.debug("Prefixing {} header for Basic Auth with 'x' to prevent browser basic auth popup",
HttpHeaders.WWW_AUTHENTICATE);
}
return headers;
}
@Override
public void close() throws IOException {

View File

@ -165,7 +165,7 @@ When authentication is required the Admin UI will presented you with a login dia
* `BasicAuthPlugin`
If your plugin of choice is not supported, you will have to interact with Solr sending HTTP requests instead of through the graphical user interface of the Admin UI. All operations supported by Admin UI can be performed through Solr's RESTful APIs.
If your plugin of choice is not supported, the Admin UI will still let you perform unrestricted operations, while for restricted operations you will need to interact with Solr by sending HTTP requests instead of through the graphical user interface of the Admin UI. All operations supported by Admin UI can be performed through Solr's RESTful APIs.
== Securing Inter-Node Requests

View File

@ -144,9 +144,9 @@ limitations under the License.
<ul id="menu">
<li id="login" class="global" ng-class="{active:page=='login'}" ng-show="http401 || currentUser"><p><a href="#/login">{{http401 ? "Login" : "Logout " + currentUser}}</a></p></li>
<div ng-show="!http401">
<li id="index" class="global" ng-class="{active:page=='index'}"><p><a href="#/">Dashboard</a></p></li>
<div ng-show="!http401">
<li id="logging" class="global" ng-class="{active:page=='logging'}"><p><a href="#/~logging">Logging</a></p>
<ul ng-show="showingLogging">
<li class="level" ng-class="{active:page=='logging-levels'}"><a href="#/~logging/level">Level</a></li>