mirror of
https://github.com/alibaba/arthas.git
synced 2024-04-21 10:21:39 +00:00
This commit is contained in:
@@ -25,6 +25,7 @@ public class ArthasConstants {
|
||||
|
||||
public static final int TELNET_PORT = 3658;
|
||||
|
||||
public static final String DEFAULT_WEBSOCKET_PATH = "/ws";
|
||||
public static final int WEBSOCKET_IDLE_SECONDS = 60;
|
||||
|
||||
/**
|
||||
@@ -35,4 +36,6 @@ public class ArthasConstants {
|
||||
public static final String DEFAULT_USERNAME = "arthas";
|
||||
public static final String SUBJECT_KEY = "subject";
|
||||
public static final String AUTH = "auth";
|
||||
public static final String USERNAME_KEY = "username";
|
||||
public static final String PASSWORD_KEY = "password";
|
||||
}
|
||||
|
||||
+34
-1
@@ -1,6 +1,8 @@
|
||||
package com.taobao.arthas.core.shell.term.impl.http;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
@@ -26,6 +28,7 @@ import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http.QueryStringDecoder;
|
||||
import io.netty.util.Attribute;
|
||||
|
||||
/**
|
||||
@@ -61,9 +64,13 @@ public final class BasicHttpAuthenticatorHandler extends ChannelDuplexHandler {
|
||||
authed = true;
|
||||
}
|
||||
|
||||
// 判断请求header里是否带有 username/password
|
||||
if (!authed) {
|
||||
// 判断请求header里是否带有 username/password
|
||||
BasicPrincipal principal = extractBasicAuthSubject(httpRequest);
|
||||
if (principal == null) {
|
||||
// 判断 url里是否有 username/password
|
||||
principal = extractBasicAuthSubjectFromUrl(httpRequest);
|
||||
}
|
||||
Subject subject = securityAuthenticator.login(principal);
|
||||
if (subject != null) {
|
||||
authed = true;
|
||||
@@ -103,6 +110,32 @@ public final class BasicHttpAuthenticatorHandler extends ChannelDuplexHandler {
|
||||
super.write(ctx, msg, promise);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从url参数里提取 ?username=hello&password=world
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
protected static BasicPrincipal extractBasicAuthSubjectFromUrl(HttpRequest request) {
|
||||
QueryStringDecoder queryDecoder = new QueryStringDecoder(request.uri());
|
||||
Map<String, List<String>> parameters = queryDecoder.parameters();
|
||||
|
||||
List<String> passwords = parameters.get(ArthasConstants.PASSWORD_KEY);
|
||||
if (passwords == null || passwords.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
String password = passwords.get(0);
|
||||
|
||||
String username = ArthasConstants.DEFAULT_USERNAME;
|
||||
List<String> usernames = parameters.get(ArthasConstants.USERNAME_KEY);
|
||||
if (usernames != null && !usernames.isEmpty()) {
|
||||
username = usernames.get(0);
|
||||
}
|
||||
BasicPrincipal principal = new BasicPrincipal(username, password);
|
||||
logger.debug("Extracted Basic Auth principal from url: {}", principal);
|
||||
return principal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the username and password details from the HTTP basic header
|
||||
* Authorization.
|
||||
|
||||
+2
-2
@@ -59,7 +59,8 @@ public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequ
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
|
||||
if (wsUri.equalsIgnoreCase(request.uri())) {
|
||||
String path = new URI(request.uri()).getPath();
|
||||
if (wsUri.equalsIgnoreCase(path)) {
|
||||
ctx.fireChannelRead(request.retain());
|
||||
} else {
|
||||
if (HttpUtil.is100ContinueExpected(request)) {
|
||||
@@ -67,7 +68,6 @@ public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequ
|
||||
}
|
||||
|
||||
HttpResponse response = null;
|
||||
String path = new URI(request.uri()).getPath();
|
||||
if ("/".equals(path)) {
|
||||
path = "/index.html";
|
||||
}
|
||||
|
||||
+2
-4
@@ -13,8 +13,6 @@ import io.netty.util.concurrent.EventExecutorGroup;
|
||||
import io.termd.core.function.Consumer;
|
||||
import io.termd.core.tty.TtyConnection;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.taobao.arthas.common.ArthasConstants;
|
||||
|
||||
/**
|
||||
@@ -42,8 +40,8 @@ public class LocalTtyServerInitializer extends ChannelInitializer<LocalChannel>
|
||||
pipeline.addLast(new HttpServerCodec());
|
||||
pipeline.addLast(new ChunkedWriteHandler());
|
||||
pipeline.addLast(new HttpObjectAggregator(ArthasConstants.MAX_HTTP_CONTENT_LENGTH));
|
||||
pipeline.addLast(workerGroup, "HttpRequestHandler", new HttpRequestHandler("/ws"));
|
||||
pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
|
||||
pipeline.addLast(workerGroup, "HttpRequestHandler", new HttpRequestHandler(ArthasConstants.DEFAULT_WEBSOCKET_PATH));
|
||||
pipeline.addLast(new WebSocketServerProtocolHandler(ArthasConstants.DEFAULT_WEBSOCKET_PATH, true));
|
||||
pipeline.addLast(new IdleStateHandler(0, 0, ArthasConstants.WEBSOCKET_IDLE_SECONDS));
|
||||
pipeline.addLast(new TtyWebSocketFrameHandler(group, handler));
|
||||
}
|
||||
|
||||
+2
-2
@@ -42,8 +42,8 @@ public class TtyServerInitializer extends ChannelInitializer<SocketChannel> {
|
||||
pipeline.addLast(new ChunkedWriteHandler());
|
||||
pipeline.addLast(new HttpObjectAggregator(ArthasConstants.MAX_HTTP_CONTENT_LENGTH));
|
||||
pipeline.addLast(new BasicHttpAuthenticatorHandler(httpSessionManager));
|
||||
pipeline.addLast(workerGroup, "HttpRequestHandler", new HttpRequestHandler("/ws"));
|
||||
pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
|
||||
pipeline.addLast(workerGroup, "HttpRequestHandler", new HttpRequestHandler(ArthasConstants.DEFAULT_WEBSOCKET_PATH));
|
||||
pipeline.addLast(new WebSocketServerProtocolHandler(ArthasConstants.DEFAULT_WEBSOCKET_PATH, true));
|
||||
pipeline.addLast(new IdleStateHandler(0, 0, ArthasConstants.WEBSOCKET_IDLE_SECONDS));
|
||||
pipeline.addLast(new TtyWebSocketFrameHandler(group, handler));
|
||||
}
|
||||
|
||||
+2
-2
@@ -93,8 +93,8 @@ public class ProtocolDetectHandler extends ChannelInboundHandlerAdapter {
|
||||
pipeline.addLast(new ChunkedWriteHandler());
|
||||
pipeline.addLast(new HttpObjectAggregator(ArthasConstants.MAX_HTTP_CONTENT_LENGTH));
|
||||
pipeline.addLast(new BasicHttpAuthenticatorHandler(httpSessionManager));
|
||||
pipeline.addLast(workerGroup, "HttpRequestHandler", new HttpRequestHandler("/ws"));
|
||||
pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
|
||||
pipeline.addLast(workerGroup, "HttpRequestHandler", new HttpRequestHandler(ArthasConstants.DEFAULT_WEBSOCKET_PATH));
|
||||
pipeline.addLast(new WebSocketServerProtocolHandler(ArthasConstants.DEFAULT_WEBSOCKET_PATH, true));
|
||||
pipeline.addLast(new IdleStateHandler(0, 0, ArthasConstants.WEBSOCKET_IDLE_SECONDS));
|
||||
pipeline.addLast(new TtyWebSocketFrameHandler(channelGroup, ttyConnectionFactory));
|
||||
ctx.fireChannelActive();
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.alibaba.arthas.tunnel.common.SimpleHttpResponse;
|
||||
import com.alibaba.arthas.tunnel.server.cluster.TunnelClusterStore;
|
||||
import com.taobao.arthas.common.ArthasConstants;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
@@ -33,12 +34,11 @@ import io.netty.util.concurrent.Promise;
|
||||
*/
|
||||
public class TunnelServer {
|
||||
private final static Logger logger = LoggerFactory.getLogger(TunnelServer.class);
|
||||
public static final String DEFAULT_WEBSOCKET_PATH = "/ws";
|
||||
|
||||
private boolean ssl;
|
||||
private String host;
|
||||
private int port;
|
||||
private String path = DEFAULT_WEBSOCKET_PATH;
|
||||
private String path = ArthasConstants.DEFAULT_WEBSOCKET_PATH;
|
||||
|
||||
private Map<String, AgentInfo> agentInfoMap = new ConcurrentHashMap<String, AgentInfo>();
|
||||
|
||||
|
||||
+2
-2
@@ -6,8 +6,8 @@ import java.util.List;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.alibaba.arthas.tunnel.server.TunnelServer;
|
||||
import com.alibaba.arthas.tunnel.server.utils.InetAddressUtil;
|
||||
import com.taobao.arthas.common.ArthasConstants;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -58,7 +58,7 @@ public class ArthasProperties {
|
||||
private String host;
|
||||
private int port;
|
||||
private boolean ssl;
|
||||
private String path = TunnelServer.DEFAULT_WEBSOCKET_PATH;
|
||||
private String path = ArthasConstants.DEFAULT_WEBSOCKET_PATH;
|
||||
|
||||
/**
|
||||
* 客户端连接的地址。也用于保存到redis里,当部署tunnel server集群里需要。不配置则会自动获取
|
||||
|
||||
Reference in New Issue
Block a user