Java的认证的HttpServer - 客户端

问题描述 投票:1回答:2

我实现了一个非常简单的HTTP服务器所描述的here。我设法得到认证通过使用认证头工作,但我无法弄清楚如何从一个形式采取的凭据,并利用它们与服务器进行身份验证。这是如何做到一般?

码:

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();
  }

}
java rest http client-side basic-authentication
2个回答
1
投票

通常,大多数人会使用像四郎或Spring Security的验证框架。

这些框架上的图案注册一个Servlet过滤器,如/*执行关于所有请求认证。它们存储在Servlet会话的认证数据,保证用户的请求,这通常是由HTTP服务器通过cookie完成隐含之间登录。他们还注册一个特殊的背景下接受基于表单的身份验证请求,如POST请求/login

这些形式的基于端点会读,通常是application/x-www-form-urlencoded,要求并拉出提交的用户名和密码,散列密码相同的方式,服务器存储的密码,并加以比较,以验证认证校长。


0
投票

Basic Authentication协议状态的客户端请求应具有的形式的标题

Authorization: Basic Base64Encoded(username:password)

其中Base64Encoded(username:password)是编码的username:password的串的实际的Base64。例如,如果我的用户名和密码peeskillet:pass,标题应该送出了

Authorization: Basic cGVlc2tpbGxldDpwYXNz

the example from your link,它使用基本身份验证。该网址到受保护的资源

http://localhost:8000/get

你可以到你的浏览器的网址,你会看到一个对话框(在Firefox)在this answer看到。输入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=

对于其他的组合,你可以在go here键入组合,或Java 8具有您可以使用编码凭据java.util.Base64

String cred = "admin:password";
String encoded = Base64.getEncoder().encodeToString(cred.getBytes());
System.out.println(encoded);
// YWRtaW46cGFzc3dvcmQ=
© www.soinside.com 2019 - 2024. All rights reserved.