![](/img/trans.png)
[英]Java httpServer basic authentication for different request methods
[英]Java HTTPServer Authentication - Client Side
我實現了一個非常簡單的HTTP服務器的描述在這里 。 我設法通過使用Authentication頭使身份驗證正常工作,但是我無法弄清楚如何從表單中獲取憑據並使用它們對服務器進行身份驗證。 通常如何做?
碼:
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.BasicAuthenticator;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class SimpleHttpServer3 {
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
server.createContext("/info", new InfoHandler());
HttpContext hc1 = server.createContext("/get", new GetHandler());
hc1.setAuthenticator(new BasicAuthenticator("get") {
@Override
public boolean checkCredentials(String user, String pwd) {
return user.equals("admin") && pwd.equals("password");
}
});
server.setExecutor(null); // creates a default executor
server.start();
System.out.println("The server is running");
}
// http://localhost:8000/info
static class InfoHandler implements HttpHandler {
public void handle(HttpExchange httpExchange) throws IOException {
String response = "Use /get to authenticate (user:admin pwd:password)";
SimpleHttpServer3.writeResponse(httpExchange, response.toString());
}
}
static class GetHandler implements HttpHandler {
public void handle(HttpExchange httpExchange) throws IOException {
StringBuilder response = new StringBuilder();
response.append("<html><body>");
response.append("hello " + httpExchange.getPrincipal().getUsername());
response.append("</body></html>");
SimpleHttpServer3.writeResponse(httpExchange, response.toString());
}
}
public static void writeResponse(HttpExchange httpExchange, String response) throws IOException {
httpExchange.sendResponseHeaders(200, response.length());
OutputStream os = httpExchange.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
通常,大多數人會使用Shiro或Spring Security等身份驗證框架。
這些框架在模式(例如/*
上注冊Servlet過濾器,以對所有請求強制執行身份驗證。 它們將身份驗證數據存儲在Servlet會話中,以使用戶在兩次請求之間登錄,這通常由HTTP服務器通過Cookies隱式完成。 他們還注冊了一個特殊的上下文來接受基於表單的身份驗證請求,例如對/login
POST請求。
這些基於表單的終結點通常會讀取application/x-www-form-urlencoded
,請求並提取提交的用戶名和密碼,以與服務器存儲密碼相同的方式對密碼進行哈希處理,並比較它們以驗證身份驗證主體。
基本身份驗證協議規定客戶端請求應具有以下形式的標頭:
Authorization: Basic Base64Encoded(username:password)
其中Base64Encoded(username:password)
是的實際Base64編碼串username:password
。 例如,如果我的用戶名和密碼是peeskillet:pass
,則標題應發送為
Authorization: Basic cGVlc2tpbGxldDpwYXNz
在鏈接的示例中 ,它使用的是基本身份驗證。 受保護資源的URL是
http://localhost:8000/get
您可以轉到瀏覽器中的URL,然后將看到一個對話框(在Firefox中),如該答案所示 。 輸入admin
(用戶名)和password
(密碼)。 您將收到hello admin
返回消息。
您不需要自己進行任何身份驗證(或至少不需要解析/解碼),就像在內部(我沒有檢查源代碼,但似乎是這樣)那樣, BasicAuthenticator
解碼並解析Authorization
標頭並傳遞您實現的checkCredentials
方法的用戶名和密碼。 由於簡單,僅允許admin/password
,因此這是將進行身份驗證的唯一組合。
僅出於完整性考慮,解碼/解析(偽代碼)可能類似於
String authHeader = request.getHeader("Authorization");
String[] split = authHeader.split("\\s");
String credentials = split[1];
String decoded = Base64.decode(credentials);
String[] userPass = decoded.split(":");
String username = userPass[0];
String password = userPass[1];
boolean authenticated = checkCredentials(username, password);
如果要嘗試使用代碼發出請求,則需要在請求中設置Authorization
標頭。 該值是admin:password
的Base64編碼的字符串,即YWRtaW46cGFzc3dvcmQ=
。 所以標題應該發送為
Authorization: Basic YWRtaW46cGFzc3dvcmQ=
對於其他組合,您可以直接在此處鍵入組合,或者Java 8具有java.util.Base64類,可用於對憑據進行編碼
String cred = "admin:password";
String encoded = Base64.getEncoder().encodeToString(cred.getBytes());
System.out.println(encoded);
// YWRtaW46cGFzc3dvcmQ=
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.