Servlet实现HTTP基本认证机制
HTTP基本认证机制
HTTP基本认证机制:http://my.oschina.net/xinxingegeya/blog/209418
在HTTP协议进行通信的过程中,HTTP协议定义了基本认证过程以允许HTTP服务器对WEB浏览器进行用户身份证的方法,当一个客户端向HTTP服务 器进行数据请求时,如果客户端未被认证,则HTTP服务器将通过基本认证过程对客户端的用户名及密码进行验证,以决定用户是否合法。客户端在接收到HTTP服务器的身份认证要求后,会提示用户输入用户名及密码,然后将用户名及密码以BASE64加密,加密后的密文将附加于请求信息中, 如当用户名为anjuta,密码为:123456时,客户端将用户名和密码用“:”合并,并将合并后的字符串用BASE64加密为密文,并于每次请求数据 时,将密文附加于请求头(Request Header)中。HTTP服务器在每次收到请求包后,根据协议取得客户端附加的用户信息(BASE64加密的用户名和密码),解开请求包,对用户名及密码进行验证,如果用 户名及密码正确,则根据客户端请求,返回客户端所需要的数据;否则,返回错误代码或重新要求客户端提供用户名及密码。
HTTP认证机制的过程
客户端进行请求
HTTP GET请求报文
GET /helloworld/AuthorizationServlet HTTP/1.1
Host: localhost:12345
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=F295C2D896E79F6C056652BF7ED51FA1
Connection: keep-alive
响应报文
HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=3AC4181CE5FD2C2770453D70D73CB7F2; Path=/helloworld/; HttpOnly
WWW-authenticate: Basic realm="personal"
Content-Type: text/html;charset=utf-8
Content-Length: 30
Date: Mon, 13 Oct 2014 11:33:36 GMT
对不起你没有权限!!
服务器端质询
服务器端进行验证。如果验证通过,则返回客户端请求的数据和服务。如果没有验证通过,则要求客户端进行验证。
质询就是上边说的响应报文,报文中有一个首部表明要进行质询
WWW-authenticate: Basic realm="personal"
HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=3AC4181CE5FD2C2770453D70D73CB7F2; Path=/helloworld/; HttpOnly
WWW-authenticate: Basic realm="personal"
Content-Type: text/html;charset=utf-8
Content-Length: 30
Date: Mon, 13 Oct 2014 11:33:36 GMT
对不起你没有权限!!
服务器端认证
当返回这个报文的时候,浏览器端回弹出一个输入用户名和密码的窗口,输入要验证的信息:
客户端提交验证信息,服务器端进行验证
输入信息之后发出的请求报文是:
GET /helloworld/AuthorizationServlet HTTP/1.1
Host: localhost:12345
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=3AC4181CE5FD2C2770453D70D73CB7F2
Connection: keep-alive
Authorization: Basic MTExOjExMQ==
该报文中含有验证信息
Authorization: Basic MTExOjExMQ==
是用base64进行加密的。。
返回要请求的数据,该响应报文如下:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 96
Date: Mon, 13 Oct 2014 11:42:29 GMT
<html>
<body>
<h2>Hello World!</h2>
<h2>Hello World!</h2>
<h2>Hello World!</h2>
</body>
</html>
通过basic验证之后,那么每次请求都会在请求首部中加入base64加密的验证信息:
如下所示的请求/helloworld/PerformanceServlet
GET /helloworld/PerformanceServlet HTTP/1.1
Host: localhost:12345
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=3AC4181CE5FD2C2770453D70D73CB7F2
Authorization: Basic MTExOjExMQ==
Connection: keep-alive
用Servlet实现HTTP基本认证机制
主要是Servlet的实现,如下:
package com.lyx.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Base64;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class AuthorizationServlet
*/
public class AuthorizationServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public AuthorizationServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* 使用基本验证机制的用户登陆逻辑
*
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String user = (String) request.getSession().getAttribute("user");
String password = null;
if (user == null) {
try {
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Type", "text/html; charset=utf-8");
PrintWriter out = response.getWriter();
String authorization = request.getHeader("authorization");
System.out.println("authorization->" + authorization);
if (authorization == null || authorization.equals("")) {
response.setStatus(401);
response.setHeader("WWW-authenticate",
"Basic realm=\"personal\"");
out.print("对不起你没有权限!!");
return;
}
String userAndPass = new String(Base64.getDecoder().decode(
authorization.split(" ")[1]));
if (userAndPass.split(":").length < 2) {
response.setStatus(401);
response.setHeader("WWW-authenticate",
"Basic realm=\"personal\"");
out.print("对不起你没有权限!!");
return;
}
user = userAndPass.split(":")[0];
password = userAndPass.split(":")[1];
if (user.equals("111") && password.equals("111")) {
request.getSession().setAttribute("user", user);
RequestDispatcher dispatcher = request
.getRequestDispatcher("index.jsp");
dispatcher.forward(request, response);
} else {
response.setStatus(401);
response.setHeader("WWW-authenticate",
"Basic realm=\"personal\"");
out.print("对不起你没有权限!!");
return;
}
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
RequestDispatcher dispatcher = request
.getRequestDispatcher("index.jsp");
dispatcher.forward(request, response);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
====END====