java

位置:IT落伍者 >> java >> 浏览文章

Java SE 6 新特性: HTTP 增强(2)


发布日期:2019年01月07日
 
Java SE 6 新特性: HTTP 增强

Authentication 提供了关于认证发起者的足够多的信息让继承类根据这些信息进行判断在 getPasswordAuthentication 方法中给出了不同的认证信息

getRequestingHost() getRequestingPort() getRequestingPrompt() getRequestingProtocol() getRequestingScheme() getRequestingURL() getRequestingSite() getRequestorType()

另一件关于 Authentication 的重要问题是认证类型不同的认证类型需要 Authentication 执行不同的协议至 Java SE 为止Authentication 支持的认证方式有

HTTP Basic authentication HTTP Digest authentication NTLM Http SPNEGO Negotiate Kerberos NTLM

这里我们着重介绍 NTLM

NTLM 是 NT LAN Manager 的缩写早期的 SMB 协议在网络上明文传输口令这是很不安全的微软随后提出了 WindowsNT 挑战/响应验证机制即 NTLM

NTLM 协议是这样的

·客户端首先将用户的密码加密成为密码散列

·客户端向服务器发送自己的用户名这个用户名是用明文直接传输的

·服务器产生一个 位的随机数字发送给客户端作为一个 challenge(挑战)

·客户端用步骤得到的密码散列来加密这个 challenge 然后把这个返回给服务器

·服务器把用户名给客户端的 challenge 客户端返回的 response 这三个东西发送域控制器

·域控制器用这个用户名在 SAM 密码管理库中找到这个用户的密码散列然后使用这个密码散列来加密 challenge

·域控制器比较两次加密的 challenge 如果一样那么认证成功

Java 以前的版本是不支持 NTLM 认证的用户若想使用 HttpConnection 连接到一个使用有 Windows 域保护的网站时是无法通过 NTLM 认证的另一种方法是用户自己用 Socket 这样的底层单元实现整个协议过程这无疑是十分复杂的

终于Java 的 Authentication 类提供了对 NTLM 的支持使用十分方便就像其他的认证协议一样

class DefaultAuthenticator extends Authenticator {private static String username = username ;private static String domain = domain ;private static String password = password ;public PasswordAuthentication getPasswordAuthentication() {String usernamewithdomain = domain + / +username;return (new PasswordAuthentication(usernamewithdomain password

            toCharArray()));}}

这里根据 Windows 域账户的命名规范账户名为域名+/+域用户名如果不想每生成 PasswordAuthentication 时每次添加域名可以设定一个系统变量名

Java 中 Authentication 的另一个特性是认证协商目前的服务器一般同时提供几种认证协议根据客户端的不同能力协商出一种认证方式比如IIS 服务器会同时提供 NTLM with kerberos 和 NTLM 两种认证方式当客户端不支持 NTLM with kerberos 时执行 NTLM 认证

目前Authentication 的默认协商次序是

GSS/SPNEGO > Digest > NTLM > Basic

那么 kerberos 的位置究竟在哪里呢?

事实上GSS/SPNEGO 以 JAAS 为基石而后者实际上就是使用 kerberos 的

轻量级 HTTP 服务器

Java 还提供了一个轻量级的纯 Java Http 服务器的实现下面是一个简单的例子

public static void main(String[] args) throws Exception{HttpServerProvider ();InetSocketAddress addr = new InetSocketAddress();HttpServer httpServer = (addr );(/myapp/ new MyHttpHandler());(null);();Systemoutprintln(started);}static class MyHttpHandler implements HttpHandler{public void handle(HttpExchange httpExchange) throws IOException { String response = Hello world!;( responselength());OutputStream out = ();outwrite(responsegetBytes());outclose();} }

上一篇:java获得当前系统内存及硬盘使用情况

下一篇:Java 传递对象给期望原始类型参数的方法