我想編寫一個環繞一組資源並需要使用基本HTTP認證來保護它們的servlet;在提供文件之前,提交的用戶名/密碼將在後端數據庫中進行檢查。在servlet中實現HTTP基本認證
有沒有人有這個工作的例子?我嘗試了http://www.coderanch.com/t/352345/Servlets/java/HTTP-basic-authentication-Web-Applications的示例,但它在sendError
調用中不斷返回IllegalStateException
。
我想編寫一個環繞一組資源並需要使用基本HTTP認證來保護它們的servlet;在提供文件之前,提交的用戶名/密碼將在後端數據庫中進行檢查。在servlet中實現HTTP基本認證
有沒有人有這個工作的例子?我嘗試了http://www.coderanch.com/t/352345/Servlets/java/HTTP-basic-authentication-Web-Applications的示例,但它在sendError
調用中不斷返回IllegalStateException
。
這是一些代碼,它返回一個Credential對象(持有登錄名和密碼的bean對象)。
public Credentials credentialsWithBasicAuthentication(HttpServletRequest req) {
String authHeader = req.getHeader("Authorization");
if (authHeader != null) {
StringTokenizer st = new StringTokenizer(authHeader);
if (st.hasMoreTokens()) {
String basic = st.nextToken();
if (basic.equalsIgnoreCase("Basic")) {
try {
String credentials = new String(Base64.decodeBase64(st.nextToken()), "UTF-8");
LOG.debug("Credentials: " + credentials);
int p = credentials.indexOf(":");
if (p != -1) {
String login = credentials.substring(0, p).trim();
String password = credentials.substring(p + 1).trim();
return new Credentials(login, password);
} else {
LOG.error("Invalid authentication token");
}
} catch (UnsupportedEncodingException e) {
LOG.warn("Couldn't retrieve authentication", e);
}
}
}
}
return null;
}
它運作良好,即使有密碼時髦的:& =/E $£。
下面是這個類的基本單元測試,使用JMock的:
public void testCredentialsWithBasicAuthentication() {
// Setup
final HttpServletRequest request = context.mock(HttpServletRequest.class);
AuthentificationHelper helper = new AuthentificationHelper();
String login = "mickael";
String password = ":&=/?é$£";
String base64Hash = Base64.encodeString(login + ":" + password);
final String authHeader = "Basic " + base64Hash;
// Expectations
context.checking(new Expectations() {
{
oneOf (request).getHeader("Authorization");
will(returnValue(authHeader));
}
});
// Execute
Credentials credentials = helper.credentialsWithBasicAuthentication(request);
// Verify
assertNotNull(credentials);
assertEquals(login, credentials.getLogin());
assertEquals(password, credentials.getPassword());
context.assertIsSatisfied();
}
關於從官方的Java文檔中使用StringTokenizer類的一點注意:「'StringTokenizer'是一個遺留類,爲了兼容性的原因,儘管在新代碼中不鼓勵使用它,但建議任何尋求這種功能的人改爲使用'String'的'split'方法或java.util.regex包。「 – xonya 2015-10-28 08:35:25
Base64類從哪裏來? – 2016-11-04 11:50:38
我有一段時間沒有用Java編碼,但是不是J2SE的Base64部分?如https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html中所示 – 2016-11-09 17:03:34
發表你的servlet – 2013-03-25 09:54:47
我只是用樣品中的鏈接。 – 2013-03-25 11:13:19
@羅伊,你的文章中的例子對我來說工作得很好。我不知道爲什麼它給你錯誤。你能否用stacktrace更新你的帖子? – 2013-03-25 11:28:06