针对不同请求方法的Java httpServer基本身份验证

Dav*_*vid 10 java rest basic-authentication httpserver

我在Java中使用一个非常简单的httpServer来进行GET,POST,PUT和DELETE的api休息.我正在使用基本身份验证,我有几个类Authentication.java和Authorisation.java,我用它来验证和检查用户的权限.

所以,问题是我希望所有用户(经过身份验证)能够从我的api休息中获取信息,但只有具有某些特权的用户才能进行POST,PUT和DELETE.那我该怎么办呢?

这就是我得到的

public class Server {

  private static HttpServer server;

  public static void start() throws IOException {

    server = HttpServer.create(new InetSocketAddress(8000), 0);
    HttpContext ctx = server.createContext("/users", new UserHandler());
    ctx.setAuthenticator(new ApiRestBasicAuthentication("users"));

    server.start();
  }

}
Run Code Online (Sandbox Code Playgroud)

这是我的ApiRestBasicAuthentication

public class ApiRestBasicAuthentication extends BasicAuthenticator {

  private UserAuthentication authentication = new UserAuthentication();

  public ApiRestBasicAuthentication(String realm) {
    super(realm);
  }

  @Override
  public boolean checkCredentials(String user, String pwd) {
    int authCode = authentication.authenticate(user, pwd);
    return authCode == UserAuthentication.USER_AUTHENTICATED;
  }

}
Run Code Online (Sandbox Code Playgroud)

现在,检查凭据仅检查用户是否经过身份验证.但我想检查一下,如果方法是POST,DELETE或PUT,我还应检查具体的凭据.但是如何在ApiRestBasicAuthentication中获取该方法?我在我的处理程序类中这样做

public void handle(HttpExchange httpExchange) throws IOException {
    String method = httpExchange.getRequestMethod();
    if ("post".equalsIgnoreCase(method)) {
      createUser(httpExchange);
    } else if ("get".equalsIgnoreCase(method)) {
      readUsers(httpExchange);
    } else if ("put".equalsIgnoreCase(method)) {
      updateUser(httpExchange);
    } else if ("delete".equalsIgnoreCase(method)) {
      deleteUser(httpExchange);
    }
  }
Run Code Online (Sandbox Code Playgroud)

也许这应该以其他方式完成.有任何想法吗?

非常感谢.

Ves*_*dov 10

一个简单的方法是更改​​您的ApiRestBasicAuthentication,如:

public class ApiRestBasicAuthentication extends BasicAuthenticator {

  private UserAuthentication authentication = new UserAuthentication();

  public ApiRestBasicAuthentication(String realm) {
    super(realm);
  }

  @Override
  public Authenticator.Result authenticate(HttpExchange exch) {
      Authenticator.Result result=super.authenticate(exch);
      if(result instanceof Authenticator.Success) {
          HttpPrincipal principal=((Authenticator.Success)result).getPrincipal();
          String requestMethod=exch.getRequestMethod();       
          if( ADD SOME LOGIC HERE FOR PRINCIPAL AND REQUEST METHOD) {
              return new return new Authenticator.Failure(401);
          }
          return result;

      }
  }

  @Override
  public boolean checkCredentials(String user, String pwd) {
    int authCode = authentication.authenticate(user, pwd);
    return authCode == UserAuthentication.USER_AUTHENTICATED;
  }

}
Run Code Online (Sandbox Code Playgroud)

并为那些您想要验证者失败的请求/用户添加一些逻辑.我在这里向您展示了如何在authenticate方法中获取方法,但您需要指定凭据的类型.


另一个解决方案是,如果你检查BasicAuthenticator的源代码,你可以看到它如何实现authenticate方法,你可以用类似的方式创建自己的实现,而不是扩展BasicAuthenticator并使用get方法而不仅仅是用户名和密码.你可以在这里看到源代码,我相信你能找到自己的方式;)

通常在企业应用程序中,您可以使用一些外部安全管理系统 - 例如,如果您使用Spring(当前Java Web应用程序中的事实标准),您可以使用spring安全性并以更具说明性的方式执行此类安全模式和过滤器