자바(JSP)에서 NTLM 프로토콜을 이용해서 윈도우 도메인 이름과 사용자 계정을 획득하는 방법이다.
<%@ page contentType="text/html; charset=UTF-8" %>
<%
String auth = request.getHeader("Authorization");
if (auth == null) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setHeader("WWW-Authenticate", "NTLM");
response.flushBuffer();
return;
// 이 응답을 받은 IE 웹 브라우저는 다시 요청을 보낸다.
}
if (auth.startsWith("NTLM ")) {
byte[] msg = new sun.misc.BASE64Decoder().decodeBuffer(auth.substring(5));
int off = 0, length, offset;
if (msg[8] == 1) {
byte z = 0;
byte[] msg1 = { (byte) 'N', (byte) 'T', (byte) 'L',
(byte) 'M', (byte) 'S', (byte) 'S', (byte) 'P', z,
(byte) 2, z, z, z, z, z, z, z, (byte) 40, z, z, z,
(byte) 1, (byte) 130, z, z, z, (byte) 2, (byte) 2,
(byte) 2, z, z, z, z, // this line is 'nonce'
z, z, z, z, z, z, z, z };
response.setContentLength(0);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
String value = "NTLM " + new sun.misc.BASE64Encoder().encodeBuffer(msg1);
// 웹로직에서는 Header 값에 CRLF 문자를 포함하면 예외가 발생함.
response.setHeader("WWW-Authenticate", value.replaceAll("\n", ""));
response.flushBuffer();
return;
// 이 응답을 받은 IE 웹 브라우저는 다시 요청을 보낸다.
} else if (msg[8] == 3) {
// 최종적으로 윈도우 도메인 이름과 사용자 계정을 도출할 수 있는 요청이다.
String remoteHost = null;
String domain = null;
String username = null;
off = 30;
length = msg[off + 17] * 256 + msg[off + 16];
offset = msg[off + 19] * 256 + msg[off + 18];
remoteHost = new String(msg, offset, length);
length = msg[off + 1] * 256 + msg[off];
offset = msg[off + 3] * 256 + msg[off + 2];
domain = new String(msg, offset, length);
length = msg[off + 9] * 256 + msg[off + 8];
offset = msg[off + 11] * 256 + msg[off + 10];
username = new String(msg, offset, length);
// 사용자 계정에 포함된 특수 문자 제거
username = username.replaceAll("\\W", "");
return;
}
}
%>
<%
String auth = request.getHeader("Authorization");
if (auth == null) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setHeader("WWW-Authenticate", "NTLM");
response.flushBuffer();
return;
// 이 응답을 받은 IE 웹 브라우저는 다시 요청을 보낸다.
}
if (auth.startsWith("NTLM ")) {
byte[] msg = new sun.misc.BASE64Decoder().decodeBuffer(auth.substring(5));
int off = 0, length, offset;
if (msg[8] == 1) {
byte z = 0;
byte[] msg1 = { (byte) 'N', (byte) 'T', (byte) 'L',
(byte) 'M', (byte) 'S', (byte) 'S', (byte) 'P', z,
(byte) 2, z, z, z, z, z, z, z, (byte) 40, z, z, z,
(byte) 1, (byte) 130, z, z, z, (byte) 2, (byte) 2,
(byte) 2, z, z, z, z, // this line is 'nonce'
z, z, z, z, z, z, z, z };
response.setContentLength(0);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
String value = "NTLM " + new sun.misc.BASE64Encoder().encodeBuffer(msg1);
// 웹로직에서는 Header 값에 CRLF 문자를 포함하면 예외가 발생함.
response.setHeader("WWW-Authenticate", value.replaceAll("\n", ""));
response.flushBuffer();
return;
// 이 응답을 받은 IE 웹 브라우저는 다시 요청을 보낸다.
} else if (msg[8] == 3) {
// 최종적으로 윈도우 도메인 이름과 사용자 계정을 도출할 수 있는 요청이다.
String remoteHost = null;
String domain = null;
String username = null;
off = 30;
length = msg[off + 17] * 256 + msg[off + 16];
offset = msg[off + 19] * 256 + msg[off + 18];
remoteHost = new String(msg, offset, length);
length = msg[off + 1] * 256 + msg[off];
offset = msg[off + 3] * 256 + msg[off + 2];
domain = new String(msg, offset, length);
length = msg[off + 9] * 256 + msg[off + 8];
offset = msg[off + 11] * 256 + msg[off + 10];
username = new String(msg, offset, length);
// 사용자 계정에 포함된 특수 문자 제거
username = username.replaceAll("\\W", "");
return;
}
}
%>
물론 이 경우에는 MS IE 웹 브라우저만을 사용해야 한다.
참고 자료
- NTLM Authentication Scheme for HTTP
- jGuru : How could I use NTLM Authentication to authenticate via Windows NT Authentication for a servlet based intranet-application ?
No comments:
Post a Comment