摘要认证实现"/>
java 摘要认证实现
摘要认证(digest authentication)
摘要认证(Digest authentication)用来提供比基础认证更高级别的安全。在RFC2617中有关于它的描述,摘要认证是一种基于挑战-应答模式的认证模型。
摘要认证与基础认证的工作原理很相似,用户先发出一个没有认证证书的请求,Web服务器回复一个带有WWW-Authenticate头的响应,指明访问所请求的资源需要证书。但是和基础认证发送以Base 64编码的用户名和密码不同,在摘要认证中服务器让客户选一个随机数(称作”nonce“),然后浏览器使用一个单向的加密函数生成一个消息摘要(message digest),该摘要是关于用户名、密码、给定的nonce值、HTTP方法,以及所请求的URL。消息摘要函数也被称为散列算法,是一种在一个方向上很容易计算,反方向却不可行的加密算法。与基础认证对比,解码基础认证中的Base 64是很容易办到的。在服务器口令中,可以指定任意的散列算法。在RFC 2617中,描述了以MD5散列函数作为默认算法。
理解
上面的一大段话是从百度上复制过来的,简单的来说,分为如下三点:
第一次向接口发起空请求
返回一个401Unauthorized未授权的信息,请求头中会带有如下的参数:
HTTP /1.1 401 Unauthorized
WWW-Authenticate:Digest
realm= ”test realm”
qop=auth,auth-int”
nonce=”66C4EF58DA7CB956BD04233FBB64E0A4”
opaque=“5ccc069c403ebaf9f0171e9517f40e41”
对上面的参数做一下说明:
• realm的值是一个简单的字符串
• qop是认证的(校验)方式
• nonce是随机数, 可以用GUID
• opaque是个随机字符串,它只是透传而已,即客户端还会原样返回过来。
• algorithm 是个字符串,用来指示用来产生分类及校验和的算法对。如果该域没指定,则认为是“MD5“算法。
客户端需要进行认证
弹出让用户输入用户名和密码的认证窗口,客户端选择一个算法,计算出密码和其他数据的摘要(response),将摘要放到Authorization的请求头中发送给服务器,如果客户端要对服务器也进行认证,这个时候,可以发送客户端随机数cnonce。
服务接受摘要,选择算法,获取数据库用户名密码,重新计算新的摘要跟客户端传输的摘要进行比较,验证是否匹配。
200 OK
一般使用MD5加密算法。
POSTMAN中的操作
第一次发起空请求
image
image
第二次请求将第一次返回的数据,和账号密码,进行加密,再次发起请求,成功
image
java代码实现:
HttpRequestUtils
public class HttpRequestUtils {
private static final Logger logger = LoggerFactory.getLogger(HttpRequestUtils.class);
static int nc = 0; //调用次数
private static final String GET = "GET";
private static final String POST = "POST";
private static final String PUT = "PUT";
private static final String DELETE = "DELETE";
/**
* 向指定URL发送DELETE方法的请求
* @param url 发送请求的URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @param username 验证所需的用户名
* @param password 验证所需的密码
* @param json 请求json字符串
* @param type 返回xml和json格式数据,默认xml,传入json返回json数据
* @return URL 所代表远程资源的响应结果
*/
public static String sendDelete(String url, String param, String username, String password, String json, String type) {
StringBuilder result = new StringBuilder();
BufferedReader in = null;
try {
String wwwAuth = sendGet(url, param); //发起一次授权请求
if (wwwAuth.startsWith("WWW-Authenticate:")) {
wwwAuth = wwwAuth.replaceFirst("WWW-Authenticate:", "");
} else {
return wwwAuth;
}
nc++;
String urlNameString = url + (StringUtils.isNotEmpty(param) ? "?" + param : "");
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
// 设置是否向connection输出,因为这个是post请求,参数要放在
// http正文内,因此需要设为true
connection.setDoOutput(true);
// Read from the connection. Defaultis true.
connection.setDoInput(true);
// 默认是 GET方式
connection.setRequestMethod(DELETE);
// 设置通用的请求属性
setRequestProperty(connection, wwwAuth, realUrl, username, password, DELETE, type);
if (!StringUtils.isEmpty(json)) {
byte[] writebytes = json.getBytes();
connection.setRequestProperty("Content-Length", String.valueOf(writebytes.length));
OutputStream outwritestream = connection.getOutputStream();
outwritestream.write(json.getBytes());
outwritestream.flush();
outwritestream.close();
}
if (connection.getResponseCode() == 200) {
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
} else {
String errResult = formatResultInfo(connection, type);
logger.info(errResult);
return errResult;
}
nc = 0;
} catch (Exception e) {
nc = 0;
throw new RuntimeException(e);
} finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.pri
更多推荐
java 摘要认证实现
发布评论