Skip to content

Commit

Permalink
0004119: Security token in header and session authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
erilong committed Oct 23, 2019
1 parent c371e91 commit 96f739e
Show file tree
Hide file tree
Showing 13 changed files with 302 additions and 282 deletions.
Expand Up @@ -271,8 +271,9 @@ private ParameterConstants() {
public final static String TRANSPORT_HTTP_COMPRESSION_DISABLED_SERVLET = "web.compression.disabled";
public final static String TRANSPORT_HTTP_COMPRESSION_LEVEL = "compression.level";
public final static String TRANSPORT_HTTP_COMPRESSION_STRATEGY = "compression.strategy";
public final static String TRANSPORT_HTTP_BASIC_AUTH_USERNAME = "http.basic.auth.username";
public final static String TRANSPORT_HTTP_BASIC_AUTH_PASSWORD = "http.basic.auth.password";
public final static String TRANSPORT_HTTP_USE_SESSION_AUTH = "http.use.session.auth";
public final static String TRANSPORT_HTTP_SESSION_EXPIRE_SECONDS = "http.session.expire.seconds";
public final static String TRANSPORT_HTTP_USE_HEADER_SECURITY_TOKEN = "http.use.header.security.token";
public final static String TRANSPORT_TYPE = "transport.type";
public final static String TRANSPORT_MAX_BYTES_TO_SYNC = "transport.max.bytes.to.sync";
public final static String TRANSPORT_MAX_ERROR_MILLIS = "transport.max.error.millis";
Expand Down
Expand Up @@ -101,7 +101,11 @@ protected void fireOffline(Exception exception, Node remoteNode, RemoteNodeStatu
}
status.setStatus(Status.BUSY);
} else if (isNotAuthenticated(exception)) {
log.warn("Authorization denied from {} at {}", new Object[] {remoteNode, syncUrl});
if (isAuthenticationExpired(exception)) {
log.debug("Authentication is required again to renew session");
} else {
log.warn("Authorization denied from {} at {}", new Object[] {remoteNode, syncUrl});
}
status.setStatus(Status.NOT_AUTHORIZED);
} else if (isSyncDisabled(exception)) {
log.warn("Sync was not enabled for {} at {}", new Object[] {remoteNode, syncUrl});
Expand Down Expand Up @@ -189,6 +193,24 @@ protected boolean isNotAuthenticated(Exception ex) {
return offline;
}

protected boolean isAuthenticationExpired(Exception ex) {
boolean expired = false;
if (ex != null) {
Throwable cause = getRootCause(ex);
AuthenticationException authException = null;
if (ex instanceof AuthenticationException) {
authException = (AuthenticationException) ex;
}
if (cause instanceof AuthenticationException) {
authException = (AuthenticationException) cause;
}
if (authException != null) {
expired = authException.isExpiredSession();
}
}
return expired;
}

protected boolean isBusy(Exception ex) {
boolean offline = false;
if (ex != null) {
Expand Down
Expand Up @@ -26,11 +26,9 @@
import java.net.SocketTimeoutException;
import java.net.URL;

import org.jumpmind.symmetric.common.ParameterConstants;
import org.jumpmind.symmetric.service.IBandwidthService;
import org.jumpmind.symmetric.service.IParameterService;
import org.jumpmind.symmetric.transport.BandwidthTestResults;
import org.jumpmind.symmetric.transport.http.HttpTransportManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -41,10 +39,7 @@ public class BandwidthService implements IBandwidthService {

protected final Logger log = LoggerFactory.getLogger(getClass());

private IParameterService parameterService;

public BandwidthService(IParameterService parameterService) {
this.parameterService = parameterService;
}

public double getDownloadKbpsFor(String syncUrl, long sampleSize, long maxTestDuration) {
Expand All @@ -70,7 +65,6 @@ protected BandwidthTestResults getDownloadResultsFor(String syncUrl, long sample
URL u = new URL(String.format("%s/bandwidth?sampleSize=%s", syncUrl, sampleSize));
bw.start();
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
setBasicAuthIfNeeded(conn);

conn.connect();
is = conn.getInputStream();
Expand All @@ -83,20 +77,12 @@ protected BandwidthTestResults getDownloadResultsFor(String syncUrl, long sample
log.info("{} was calculated to have a download bandwidth of {} kbps", syncUrl, bw.getKbps());
return bw;
} finally {
if(is != null) {
try {
is.close();
} catch(IOException e) { }
}
}
}

protected void setBasicAuthIfNeeded(HttpURLConnection conn) {
if (parameterService != null) {
HttpTransportManager.setBasicAuthIfNeeded(conn, parameterService
.getString(ParameterConstants.TRANSPORT_HTTP_BASIC_AUTH_USERNAME),
parameterService
.getString(ParameterConstants.TRANSPORT_HTTP_BASIC_AUTH_PASSWORD));
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
}
}

Expand Down
Expand Up @@ -25,4 +25,17 @@ public class AuthenticationException extends OfflineException {

private static final long serialVersionUID = -6322765147037755510L;

private boolean isExpiredSession;

public AuthenticationException() {
}

public AuthenticationException(boolean isExpiredSession) {
this.isExpiredSession = isExpiredSession;
}

public boolean isExpiredSession() {
return isExpiredSession;
}

}
Expand Up @@ -55,14 +55,24 @@ public class HttpIncomingTransport implements IIncomingTransport {

private int httpTimeout;

private String redirectionUrl;

private String redirectionUrl;

private String nodeId;

private String securityToken;

public HttpIncomingTransport(HttpURLConnection connection, IParameterService parameterService) {
this.connection = connection;
this.parameterService = parameterService;
this.parameterService = parameterService;
this.httpTimeout = parameterService.getInt(ParameterConstants.TRANSPORT_HTTP_TIMEOUT);
}


public HttpIncomingTransport(HttpURLConnection connection, IParameterService parameterService, String nodeId, String securityToken) {
this(connection, parameterService);
this.nodeId = nodeId;
this.securityToken = securityToken;
}

@Override
public String getUrl() {
return this.connection.getURL().toExternalForm();
Expand All @@ -71,17 +81,19 @@ public String getUrl() {
@Override
public void close() {
if (reader != null) {
try {
reader.close();
} catch(IOException e) { }
reader = null;
}

try {
reader.close();
} catch (IOException e) {
}
reader = null;
}

if (is != null) {
try {
is.close();
} catch(IOException e) { }
is = null;
try {
is.close();
} catch (IOException e) {
}
is = null;
}
}

Expand Down Expand Up @@ -116,7 +128,11 @@ public InputStream openStream() throws IOException {
case WebConstants.SC_SERVICE_UNAVAILABLE:
throw new ServiceUnavailableException();
case WebConstants.SC_FORBIDDEN:
HttpTransportManager.clearSession(connection);
throw new AuthenticationException();
case WebConstants.SC_AUTH_EXPIRED:
HttpTransportManager.clearSession(connection);
throw new AuthenticationException(true);
case WebConstants.SC_NO_CONTENT:
throw new NoContentException();
case WebConstants.SC_OK:
Expand Down Expand Up @@ -159,52 +175,38 @@ private HttpURLConnection openConnectionCheckRedirects(HttpURLConnection connect
{
boolean redir;
int redirects = 0;
do
{
do {
connection.setInstanceFollowRedirects(false);
redir = false;
int stat = connection.getResponseCode();
if (stat >= 300 && stat <= 307 && stat != 306 &&
stat != HttpURLConnection.HTTP_NOT_MODIFIED)
{
if (stat >= 300 && stat <= 307 && stat != 306 && stat != HttpURLConnection.HTTP_NOT_MODIFIED) {
URL base = connection.getURL();
redirectionUrl = connection.getHeaderField("Location");

URL target = null;
if (redirectionUrl != null)
{
if (redirectionUrl != null) {
target = new URL(base, redirectionUrl);
}
connection.disconnect();
// Redirection should be allowed only for HTTP and HTTPS
// and should be limited to 5 redirections at most.
if (target == null || !(target.getProtocol().equals("http")
|| target.getProtocol().equals("https"))
|| redirects >= 5)
{
|| redirects >= 5) {
throw new SecurityException("illegal URL redirect");
}
redir = true;
connection = HttpTransportManager.openConnection(target, getBasicAuthUsername(), getBasicAuthPassword());
connection = HttpTransportManager.openConnection(target, nodeId, securityToken);
connection.setConnectTimeout(httpTimeout);
connection.setReadTimeout(httpTimeout);

redirects++;
}
}
while (redir);
} while (redir);

return connection;
}

protected String getBasicAuthUsername() {
return parameterService.getString(ParameterConstants.TRANSPORT_HTTP_BASIC_AUTH_USERNAME);
}

protected String getBasicAuthPassword() {
return parameterService.getString(ParameterConstants.TRANSPORT_HTTP_BASIC_AUTH_PASSWORD);
}

public HttpURLConnection getConnection() {
return connection;
}
Expand Down

0 comments on commit 96f739e

Please sign in to comment.