mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-27 09:00:28 +08:00
Stop brute force counter increase on no user/pass
Also removed RequestInternal from use. Affects issues: - Fixed #1393 - Fixes random issue where 403 is shown after one bad password input and successful login.
This commit is contained in:
parent
d6a7a43428
commit
90064d3f33
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.delivery.webserver;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Guards against password brute-force break attempts.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PassBruteForceGuard {
|
||||
|
||||
private static final int ATTEMPT_LIMIT = 3;
|
||||
private final Cache<String, Integer> failedLoginAttempts = Caffeine.newBuilder()
|
||||
.expireAfterWrite(90, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
public boolean shouldPreventRequest(String accessor) {
|
||||
Integer attempts = failedLoginAttempts.getIfPresent(accessor);
|
||||
if (attempts == null) return false;
|
||||
// Too many attempts, forbid further attempts.
|
||||
return attempts >= ATTEMPT_LIMIT;
|
||||
}
|
||||
|
||||
// Don't call on first connection.
|
||||
public void increaseAttemptCountOnFailedLogin(String accessor) {
|
||||
// Authentication was attempted, but failed so new attempt is going to be given if not forbidden
|
||||
failedLoginAttempts.cleanUp();
|
||||
|
||||
Integer attempts = failedLoginAttempts.getIfPresent(accessor);
|
||||
if (attempts == null) {
|
||||
attempts = 0;
|
||||
}
|
||||
|
||||
// Too many attempts, forbid further attempts.
|
||||
if (attempts >= ATTEMPT_LIMIT) {
|
||||
// Attempts only increased if less than ATTEMPT_LIMIT attempts to prevent frustration from the cache timer resetting.
|
||||
return;
|
||||
}
|
||||
|
||||
failedLoginAttempts.put(accessor, attempts + 1);
|
||||
}
|
||||
|
||||
public void resetAttemptCount(String accessor) {
|
||||
// Successful login
|
||||
failedLoginAttempts.cleanUp();
|
||||
failedLoginAttempts.invalidate(accessor);
|
||||
}
|
||||
|
||||
public static class Disabled extends PassBruteForceGuard {
|
||||
@Override
|
||||
public boolean shouldPreventRequest(String accessor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increaseAttemptCountOnFailedLogin(String accessor) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetAttemptCount(String accessor) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -17,29 +17,34 @@
|
||||
package com.djrapitops.plan.delivery.webserver;
|
||||
|
||||
import com.djrapitops.plan.delivery.web.resolver.Response;
|
||||
import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
||||
import com.djrapitops.plan.delivery.web.resolver.request.URIPath;
|
||||
import com.djrapitops.plan.delivery.web.resolver.request.URIQuery;
|
||||
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
|
||||
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
|
||||
import com.djrapitops.plan.delivery.webserver.auth.BasicAuthentication;
|
||||
import com.djrapitops.plan.delivery.webserver.auth.FailReason;
|
||||
import com.djrapitops.plan.exceptions.WebUserAuthException;
|
||||
import com.djrapitops.plan.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.settings.config.paths.PluginSettings;
|
||||
import com.djrapitops.plan.settings.config.paths.WebserverSettings;
|
||||
import com.djrapitops.plan.settings.locale.Locale;
|
||||
import com.djrapitops.plan.storage.database.DBSystem;
|
||||
import com.djrapitops.plugin.logging.L;
|
||||
import com.djrapitops.plugin.logging.console.PluginLogger;
|
||||
import com.djrapitops.plugin.logging.error.ErrorHandler;
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.sun.net.httpserver.Headers;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.text.TextStringBuilder;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* HttpHandler for WebServer request management.
|
||||
@ -49,7 +54,6 @@ import java.util.concurrent.TimeUnit;
|
||||
@Singleton
|
||||
public class RequestHandler implements HttpHandler {
|
||||
|
||||
private final Locale locale;
|
||||
private final PlanConfig config;
|
||||
private final DBSystem dbSystem;
|
||||
private final Addresses addresses;
|
||||
@ -58,13 +62,10 @@ public class RequestHandler implements HttpHandler {
|
||||
private final PluginLogger logger;
|
||||
private final ErrorHandler errorHandler;
|
||||
|
||||
private final Cache<String, Integer> failedLoginAttempts = Caffeine.newBuilder()
|
||||
.expireAfterWrite(90, TimeUnit.SECONDS)
|
||||
.build();
|
||||
private PassBruteForceGuard bruteForceGuard;
|
||||
|
||||
@Inject
|
||||
RequestHandler(
|
||||
Locale locale,
|
||||
PlanConfig config,
|
||||
DBSystem dbSystem,
|
||||
Addresses addresses,
|
||||
@ -73,7 +74,6 @@ public class RequestHandler implements HttpHandler {
|
||||
PluginLogger logger,
|
||||
ErrorHandler errorHandler
|
||||
) {
|
||||
this.locale = locale;
|
||||
this.config = config;
|
||||
this.dbSystem = dbSystem;
|
||||
this.addresses = addresses;
|
||||
@ -81,33 +81,16 @@ public class RequestHandler implements HttpHandler {
|
||||
this.responseFactory = responseFactory;
|
||||
this.logger = logger;
|
||||
this.errorHandler = errorHandler;
|
||||
|
||||
bruteForceGuard = new PassBruteForceGuard();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(HttpExchange exchange) {
|
||||
Headers requestHeaders = exchange.getRequestHeaders();
|
||||
|
||||
RequestInternal request = new RequestInternal(exchange, locale);
|
||||
request.setAuth(getAuthorization(requestHeaders));
|
||||
|
||||
try {
|
||||
Response response = shouldPreventRequest(request.getRemoteAddress()) // Forbidden response (Optional)
|
||||
.orElseGet(() -> responseResolver.getResponse(request)); // Or the actual requested response
|
||||
|
||||
// Increase attempt count and block if too high
|
||||
Optional<Response> forbid = handlePasswordBruteForceAttempts(request, response);
|
||||
if (forbid.isPresent()) {
|
||||
response = forbid.get();
|
||||
}
|
||||
|
||||
// Authentication failed, but was not blocked
|
||||
// if (response.getCode() == 401) {
|
||||
//// responseHeaders.set("WWW-Authenticate", Optional.ofNullable(response.getHeaders().get("WWW-Authenticate")).orElse("Basic realm=\"Plan WebUser (/plan register)\""));
|
||||
//// }
|
||||
|
||||
Response response = getResponse(exchange);
|
||||
response.getHeaders().putIfAbsent("Access-Control-Allow-Origin", config.get(WebserverSettings.CORS_ALLOW_ORIGIN));
|
||||
response.getHeaders().putIfAbsent("Access-Control-Allow-Methods", "GET, OPTIONS");
|
||||
|
||||
ResponseSender sender = new ResponseSender(addresses, exchange, response);
|
||||
sender.send();
|
||||
} catch (Exception e) {
|
||||
@ -120,63 +103,71 @@ public class RequestHandler implements HttpHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<Response> shouldPreventRequest(String accessor) {
|
||||
Integer attempts = failedLoginAttempts.getIfPresent(accessor);
|
||||
if (attempts == null) {
|
||||
attempts = 0;
|
||||
}
|
||||
|
||||
// Too many attempts, forbid further attempts.
|
||||
if (attempts >= 5) {
|
||||
return createForbiddenResponse();
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private Optional<Response> handlePasswordBruteForceAttempts(RequestInternal request, Response response) {
|
||||
if (request.getAuth().isPresent() && response.getCode() == 401) {
|
||||
// Authentication was attempted, but failed so new attempt is going to be given if not forbidden
|
||||
|
||||
failedLoginAttempts.cleanUp();
|
||||
|
||||
String accessor = request.getRemoteAddress();
|
||||
Integer attempts = failedLoginAttempts.getIfPresent(accessor);
|
||||
if (attempts == null) {
|
||||
attempts = 0;
|
||||
public Response getResponse(HttpExchange exchange) {
|
||||
String accessor = exchange.getRemoteAddress().getAddress().getHostAddress();
|
||||
Request request;
|
||||
Response response;
|
||||
try {
|
||||
request = buildRequest(exchange);
|
||||
if (bruteForceGuard.shouldPreventRequest(accessor)) {
|
||||
response = responseFactory.failedLoginAttempts403();
|
||||
} else {
|
||||
response = responseResolver.getResponse(request);
|
||||
}
|
||||
|
||||
// Too many attempts, forbid further attempts.
|
||||
if (attempts >= 5) {
|
||||
logger.warn(accessor + " failed to login 5 times. Their access is blocked for 90 seconds.");
|
||||
return createForbiddenResponse();
|
||||
} catch (WebUserAuthException thrownByAuthentication) {
|
||||
if (thrownByAuthentication.getFailReason() != FailReason.USER_AND_PASS_NOT_SPECIFIED) {
|
||||
bruteForceGuard.increaseAttemptCountOnFailedLogin(accessor);
|
||||
}
|
||||
|
||||
// Attempts only increased if less than 5 attempts to prevent frustration from the cache value not
|
||||
// getting removed.
|
||||
failedLoginAttempts.put(accessor, attempts + 1);
|
||||
} else if (response.getCode() != 401 && response.getCode() != 403) {
|
||||
// Successful login
|
||||
failedLoginAttempts.invalidate(request.getRemoteAddress());
|
||||
response = responseFactory.basicAuthFail(thrownByAuthentication);
|
||||
}
|
||||
// First connection, no authentication headers present.
|
||||
return Optional.empty();
|
||||
|
||||
if (bruteForceGuard.shouldPreventRequest(accessor)) {
|
||||
response = responseFactory.failedLoginAttempts403();
|
||||
}
|
||||
if (response.getCode() != 401 && response.getCode() != 403) {
|
||||
bruteForceGuard.resetAttemptCount(accessor);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
private Optional<Response> createForbiddenResponse() {
|
||||
return Optional.of(responseFactory.forbidden403("You have too many failed login attempts. Please wait 2 minutes until attempting again."));
|
||||
private Request buildRequest(HttpExchange exchange) {
|
||||
String requestMethod = exchange.getRequestMethod();
|
||||
URIPath path = new URIPath(exchange.getRequestURI().getPath());
|
||||
URIQuery query = new URIQuery(exchange.getRequestURI().getQuery());
|
||||
WebUser user = getWebUser(exchange);
|
||||
Map<String, String> headers = getRequestHeaders(exchange);
|
||||
return new Request(requestMethod, path, query, user, headers);
|
||||
}
|
||||
|
||||
private Authentication getAuthorization(Headers requestHeaders) {
|
||||
private WebUser getWebUser(HttpExchange exchange) {
|
||||
return getAuthorization(exchange.getRequestHeaders())
|
||||
.map(Authentication::getWebUser) // Can throw WebUserAuthException
|
||||
.map(com.djrapitops.plan.delivery.domain.WebUser::toNewWebUser)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private Map<String, String> getRequestHeaders(HttpExchange exchange) {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
for (Map.Entry<String, List<String>> e : exchange.getResponseHeaders().entrySet()) {
|
||||
List<String> value = e.getValue();
|
||||
headers.put(e.getKey(), new TextStringBuilder().appendWithSeparators(value, ";").build());
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
private Optional<Authentication> getAuthorization(Headers requestHeaders) {
|
||||
if (config.isTrue(WebserverSettings.DISABLED_AUTHENTICATION)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
List<String> authorization = requestHeaders.get("Authorization");
|
||||
if (Verify.isEmpty(authorization)) {
|
||||
return null;
|
||||
}
|
||||
if (Verify.isEmpty(authorization)) return Optional.empty();
|
||||
|
||||
String authLine = authorization.get(0);
|
||||
if (StringUtils.contains(authLine, "Basic ")) {
|
||||
return new BasicAuthentication(StringUtils.split(authLine, ' ')[1], dbSystem.getDatabase());
|
||||
return Optional.of(new BasicAuthentication(StringUtils.split(authLine, ' ')[1], dbSystem.getDatabase()));
|
||||
}
|
||||
return null;
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public ResponseResolver getResponseResolver() {
|
||||
|
@ -1,127 +0,0 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.delivery.webserver;
|
||||
|
||||
import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
||||
import com.djrapitops.plan.delivery.web.resolver.request.URIPath;
|
||||
import com.djrapitops.plan.delivery.web.resolver.request.URIQuery;
|
||||
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
|
||||
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
|
||||
import com.djrapitops.plan.exceptions.WebUserAuthException;
|
||||
import com.djrapitops.plan.settings.locale.Locale;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents a HttpExchange Request.
|
||||
* <p>
|
||||
* Automatically gets the Basic Auth from headers.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class RequestInternal {
|
||||
private final String requestMethod;
|
||||
|
||||
private final URI requestURI;
|
||||
|
||||
private final HttpExchange exchange;
|
||||
private final String remoteAddress;
|
||||
private final Locale locale;
|
||||
private Authentication auth;
|
||||
|
||||
public RequestInternal(HttpExchange exchange, Locale locale) {
|
||||
this.requestMethod = exchange.getRequestMethod();
|
||||
requestURI = exchange.getRequestURI();
|
||||
|
||||
remoteAddress = exchange.getRemoteAddress().getAddress().getHostAddress();
|
||||
|
||||
this.exchange = exchange;
|
||||
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public Optional<Authentication> getAuth() {
|
||||
return Optional.ofNullable(auth);
|
||||
}
|
||||
|
||||
public void setAuth(Authentication authentication) {
|
||||
auth = authentication;
|
||||
}
|
||||
|
||||
public String getRequestMethod() {
|
||||
return requestMethod;
|
||||
}
|
||||
|
||||
public String getTargetString() {
|
||||
return requestURI.getPath() + '?' + requestURI.getQuery();
|
||||
}
|
||||
|
||||
public URIPath getPath() {
|
||||
return new URIPath(requestURI.getPath());
|
||||
}
|
||||
|
||||
public URIQuery getQuery() {
|
||||
return new URIQuery(requestURI.getQuery());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Request:" + requestMethod + " " + requestURI.getPath();
|
||||
}
|
||||
|
||||
public String getRemoteAddress() {
|
||||
return remoteAddress;
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn the internal Request to a Page Extension API request object.
|
||||
*
|
||||
* @return different representation.
|
||||
* @throws WebUserAuthException If the user could not be authenticated.
|
||||
*/
|
||||
public Request toAPIRequest() {
|
||||
return new Request(
|
||||
requestMethod,
|
||||
getPath(),
|
||||
getQuery(),
|
||||
getWebUser(),
|
||||
getRequestHeaders()
|
||||
);
|
||||
}
|
||||
|
||||
private WebUser getWebUser() {
|
||||
return getAuth().map(authentication -> authentication.getWebUser().toNewWebUser()).orElse(null);
|
||||
}
|
||||
|
||||
private Map<String, String> getRequestHeaders() {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
for (Map.Entry<String, List<String>> e : exchange.getResponseHeaders().entrySet()) {
|
||||
List<String> value = e.getValue();
|
||||
headers.put(e.getKey(), value.toString().substring(0, value.size() - 1));
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
}
|
@ -334,6 +334,15 @@ public class ResponseFactory {
|
||||
}
|
||||
}
|
||||
|
||||
public Response failedLoginAttempts403() {
|
||||
return Response.builder()
|
||||
.setMimeType(MimeType.HTML)
|
||||
.setContent("<h1>403 Forbidden</h1>" +
|
||||
"<p>You have too many failed login attempts. Please wait 2 minutes until attempting again.</p>")
|
||||
.setStatus(403)
|
||||
.build();
|
||||
}
|
||||
|
||||
public Response basicAuth() {
|
||||
try {
|
||||
String tips = "<br>- Ensure you have registered a user with <b>/plan register</b><br>"
|
||||
|
@ -24,10 +24,9 @@ import com.djrapitops.plan.delivery.web.resolver.Response;
|
||||
import com.djrapitops.plan.delivery.web.resolver.exception.BadRequestException;
|
||||
import com.djrapitops.plan.delivery.web.resolver.exception.NotFoundException;
|
||||
import com.djrapitops.plan.delivery.web.resolver.request.Request;
|
||||
import com.djrapitops.plan.delivery.webserver.auth.Authentication;
|
||||
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
|
||||
import com.djrapitops.plan.delivery.webserver.resolver.*;
|
||||
import com.djrapitops.plan.delivery.webserver.resolver.json.RootJSONResolver;
|
||||
import com.djrapitops.plan.exceptions.WebUserAuthException;
|
||||
import com.djrapitops.plan.exceptions.connection.ForbiddenException;
|
||||
import com.djrapitops.plugin.logging.L;
|
||||
import com.djrapitops.plugin.logging.error.ErrorHandler;
|
||||
@ -106,46 +105,41 @@ public class ResponseResolver {
|
||||
resolverService.registerResolver(plugin, "/v1", rootJSONResolver.getResolver());
|
||||
}
|
||||
|
||||
public Response getResponse(RequestInternal request) {
|
||||
public Response getResponse(Request request) {
|
||||
try {
|
||||
return tryToGetResponse(request);
|
||||
} catch (NotFoundException e) {
|
||||
return responseFactory.notFound404(e.getMessage());
|
||||
} catch (WebUserAuthException e) {
|
||||
return responseFactory.basicAuthFail(e);
|
||||
} catch (ForbiddenException e) {
|
||||
return responseFactory.forbidden403(e.getMessage());
|
||||
} catch (BadRequestException e) {
|
||||
return responseFactory.badRequest(e.getMessage(), request.getTargetString());
|
||||
return responseFactory.badRequest(e.getMessage(), request.getPath().asString());
|
||||
} catch (Exception e) {
|
||||
errorHandler.log(L.ERROR, this.getClass(), e);
|
||||
return responseFactory.internalErrorResponse(e, request.getTargetString());
|
||||
return responseFactory.internalErrorResponse(e, request.getPath().asString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NotFoundException In some cases when page was not found, not all.
|
||||
* @throws WebUserAuthException If user could not be authenticated
|
||||
* @throws ForbiddenException If the user is not allowed to see the page
|
||||
* @throws BadRequestException If the request did not have required things.
|
||||
* @throws NotFoundException In some cases when page was not found, not all.
|
||||
* @throws ForbiddenException If the user is not allowed to see the page
|
||||
* @throws BadRequestException If the request did not have required things.
|
||||
*/
|
||||
private Response tryToGetResponse(RequestInternal internalRequest) {
|
||||
if ("OPTIONS".equalsIgnoreCase(internalRequest.getRequestMethod())) {
|
||||
private Response tryToGetResponse(Request request) {
|
||||
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
|
||||
return Response.builder().setStatus(204).setContent(new byte[0]).build();
|
||||
}
|
||||
|
||||
Optional<Authentication> authentication = internalRequest.getAuth();
|
||||
Optional<WebUser> user = request.getUser();
|
||||
|
||||
List<Resolver> foundResolvers = resolverService.getResolvers(internalRequest.getPath().asString());
|
||||
List<Resolver> foundResolvers = resolverService.getResolvers(request.getPath().asString());
|
||||
if (foundResolvers.isEmpty()) return responseFactory.pageNotFound404();
|
||||
|
||||
for (Resolver resolver : foundResolvers) {
|
||||
Request request = internalRequest.toAPIRequest();
|
||||
if (resolver.requiresAuth(request)) {
|
||||
// Get required auth
|
||||
boolean isAuthRequired = webServer.get().isAuthRequired();
|
||||
if (isAuthRequired && !authentication.isPresent()) {
|
||||
boolean isAuthRequired = webServer.get().isAuthRequired() && resolver.requiresAuth(request);
|
||||
if (isAuthRequired) {
|
||||
if (!user.isPresent()) {
|
||||
if (webServer.get().isUsingHTTPS()) {
|
||||
return responseFactory.basicAuth();
|
||||
} else {
|
||||
@ -153,7 +147,7 @@ public class ResponseResolver {
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAuthRequired || resolver.canAccess(request)) {
|
||||
if (resolver.canAccess(request)) {
|
||||
Optional<Response> resolved = resolver.resolve(request);
|
||||
if (resolved.isPresent()) return resolved.get();
|
||||
} else {
|
||||
|
@ -26,6 +26,8 @@ import com.djrapitops.plan.utilities.Base64Util;
|
||||
import com.djrapitops.plan.utilities.PassEncryptUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Authentication handling for Basic Auth.
|
||||
* <p>
|
||||
@ -50,7 +52,7 @@ public class BasicAuthentication implements Authentication {
|
||||
|
||||
String[] userInfo = StringUtils.split(decoded, ':');
|
||||
if (userInfo.length != 2) {
|
||||
throw new WebUserAuthException(FailReason.USER_AND_PASS_NOT_SPECIFIED);
|
||||
throw new WebUserAuthException(FailReason.USER_AND_PASS_NOT_SPECIFIED, Arrays.toString(userInfo));
|
||||
}
|
||||
|
||||
String user = userInfo[0];
|
||||
|
Loading…
Reference in New Issue
Block a user