Programming - cpueblo.com

[웹글] 인증이 필요한 웹서버 접속하기(HTTP Authorization - Basic)


글쓴이 : 유광희 날짜 : 2011-01-20 (목) 16:46 조회 : 21768

출처 : http://c-612.tistory.com/66

인증이 필요한 웹서버에 접속할때 일반적으로 브라우저는 별도의 창을 보여주고 사용자명(user)과 열쇠글(password)를 요구한다.


하지만, 프로그램의 내부에서 Http클라이언트를 생성하거나, 스크립트등으로 직접 서버에 접속할 경우에는 조금 다른 방법이 필요하게 된다.


일반적인 브라우저 사용시의 처리는 다음과 같다.

   1. 서버가 요청(request)에 대한 응답(response)으로 401에러를 반환하고

   2. 브라우저가 사용자에게 인증용 정보를 요구하는 화면을 통해 정보를 입력받아

   3. 서버에게 인증정보를 덧붙인 요청(최초의 요청 + 인증정보)을 보내고

   4. 인증정보가 올바르면 서버는 요청된 자원의 응답을 보내준다.


401에러 응답 헤더의 예


HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="My Secret Server"  이부분으로 인증종류를 판별
Content-type: text/html
Date: Sat, 27 Feb 2010 10:57:43 GMT
Server: mcas/3.0 (RV230NE Ver 8.20; B2BUA; NTTEAST)
Pragma: no-cache
Cache-Control: no-store, no-cache, must-revalidate
Expires: 0
Connection: close
Content-Length: 2840
Status: 401

여기서 세번째의 인증정보를 덧붙인 요청을 처음부터 보내게 되면 요청을 재송신 할 필요없이 한번에 받는것이 가능해 진다.


이때 사용되는 것이 Authorization 헤더항목이다.


헤더의 설정은 일반적인 Http 헤더의 설정과 동일하다. 단 주의할점은 사용자명과 열쇠글은 Base64인코딩이 필요하다.


Authorization: Basic Base64인코딩된사용자명:열쇠글

  * Basic 인증만 다룬다.(다른 인증방법에 대해선 참고자료를 참조)

  * 사용자명:열쇠글 을 하나의 문자열로 보고 Base64인코딩을 한다

예) 사용자명 "Aladdin", 열쇠글 "open sesame"

-> 인코딩할 문자열 "Aladdin:open sesame"

-> 인코딩된 문자열 "QWxhZGRpbjpvcGVuIHNlc2FtZQ=="



테스트

간단하게 telnet을 이용해서 테스트를 해보자

   * 주의 : Base64인코딩을 할수 있어야 한다. 여기서는 파이선을 사용했음.

telnet을 이용해서 서버에 접속한다. 단 포트는 80(Http)번으로 지정한다.

  telnet 서버명(또는 IP주소) 80

  GET 명령으로 특정 자원을 요청

  요청 헤더에 인증정보를 추가한다

  요청을 보낸다.



첫번째 시도 - 401 에러 발생


hyunt@debian:~$ telnet 192.168.1.1 80
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.
GET http://ntt.setup/index.cgi/info_main HTTP/1.1
Host: ntt.setup     <- 마지막에 엔터키를 두번 입력할것

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="My Secret Server"
Content-type: text/html
Date: Sat, 27 Feb 2010 10:57:43 GMT
Server: mcas/3.0 (RV230NE Ver 8.20; B2BUA; NTTEAST)
Pragma: no-cache
Cache-Control: no-store, no-cache, must-revalidate
Expires: 0
Connection: close
Content-Length: 2840
Status: 401
 -- 이하 생략 --



두번째 시도 - 200 (성공)


hyunt@debian:~$ telnet 192.168.1.1 80
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.
GET http://ntt.setup/index.cgi/info_main HTTP/1.1
Host: ntt.setup
Authorization: Basic dXNlcklkOnBhc3N3b3Jk  <- 마지막에 엔터키를 두번 입력할것

HTTP/1.1 200 OK
Content-type: text/html
Date: Sat, 27 Feb 2010 11:54:16 GMT
Server: mcas/3.0 (RV230NE Ver 8.20; B2BUA; NTTEAST)
Pragma: no-cache
Cache-Control: no-store, no-cache, must-revalidate
Expires: 0
Connection: close
Content-Length: 22169
Status: 200

<?xml version='1.0' encoding='EUC-JP'?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='ja' lang='ja'>
-- 이하 생략 --


Base64인코딩하기

debian:~# python
Python 2.5.2 (r252:60911, Jan 24 2010, 21:03:09)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import base64
>>> base64.encodestring('userId:password')
'dXNlcklkOnBhc3N3b3Jk\n'
>>> exit()
debian:~#


실제로 응용을 하게 된다면 헤더의 항목에 "Authorization" 을 추가해 주는것만 기억해두면 될듯.(각 언어별 설정방법은 생략.)


----------------------------------------------------

wget 이용하기

처음에 이 자료를 찾아본 이유가 리눅스 서버에서 인터넷 단말의 정보를 긁어오는 스크립트가 필요했는데 인증에서 막힌것이 원인이었다. 텔넷으로 성공한뒤 wget이 뒤늦게 생각났다고나 할까...휴.

사실, wget을 이용하면 위에서 설명했던 부분들이 필요하지 않다.

wget의 옵션에 인증시 필요한 사용자명과 열쇠글을 설정하는것이 가능하다.

   * --http-user, --http-password 이용

debian:~# wget --http-user=userId --http-password=password http://ntt.setup/index.cgi/info_main
--2010-07-15 00:59:40--  http://ntt.setup/index.cgi/info_main
Resolving ntt.setup... 192.168.1.1
Connecting to ntt.setup|192.168.1.1|:80... connected.
HTTP request sent, awaiting response... 401 Unauthorized
Connecting to ntt.setup|192.168.1.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 22169 (22K) [text/html]
Saving to: `info_main'

100%[==========================================================================>] 22,169      --.-K/s   in 0.01s  

2010-07-15 00:59:47 (2.21 MB/s) - `info_main' saved [22169/22169]

debian:~#



[참고]

HTTP 헤더 필드 정의 : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

HTTP 인증 관련 명세 : http://www.ietf.org/rfc/rfc2617.txt

HTTP 인증 이해 : http://msdn.microsoft.com/ko-kr/library/ms789031.aspx

파이선 Base64 인코딩 : http://snippets.dzone.com/posts/show/1618

wget : Man페이지