평창 여행

사는이야기 2009. 9. 27. 09:40

송과장님이 휴가로 평창에 몇일간 쉬러 가신다기에 금욜날 끝나고 출발하여 함께 했다.

마침 본사 PVT 가 있었고  ( 하필 그것도 USN1이 걸려서 하루에 두대를 PVT )

마침 Node1 PVT 후 Issue가 발생하여 두 시간 정도 대기하는 바람에 더 늦어 지고

하는 수 없이 일단 출발하고 나는 T-Login으로 작업을 하기로 했는데

이효석 문화관에서 다들 주변 관광하는 동안 나는 차안에서 PVT하고

결국 식사하러 가서야 PVT를 끝낼 수 있었다.

사실 일하느라 곳곳에 보이는 아름다운 풍경을 다 느끼지 못해서 아쉽기는 하지만

그래도 오랜만에 밖에 나가 호젓한 정취를 느낄 수 있었다.

특히 이효석 생가 ( 생가터에는 이미 음식점이 들어서서 다른 지역에 복원했다고 한다.)터에 단체 관람객이 계신 덕분에 생가와 평양 시절 ( 숭실전문대 선생님을 하셨단다... 생각해보니 학교 홍보자료 같은 데서 본 기억이 살 짝 난다.) 지내셨던 집 복원한 사정이나 간단한 그 분의 인생 얘기를 듣게 되었다.

그리고 주변에 핀 메밀 밭도 구경하고...
식당가서 사진으로 나마 메밀 꽃 밭을 찍은 모습도 보고
( 다들 내년 봄에 다시 오시겠다는.. )

평창 곳곳에서 "메밀꽃 필 무렵"의 정취를 느낄 수 있었다.

올라오면서 원경이 시험끝나면 송과장님 처럼 호젓한 팬션 하나 빌려서 몇 일 쉬고 오는 것도 좋겠다는 생각이 들었다.

PVT 때문에 좀 그랬지만 나름 즐거운 여행 길이 었다.

뭐.. 그리고 T-Login으로 PVT 진행하면서 참 우리나라 IT 기술이 이렇게 발전했다는 것을 새삼 느낄 수 있었다.

Posted by headiron
,
지난주에 개발자 행사로 안철수씨의 동영상 인터뷰를 보게 됐다.

얼마전에 무릎팍도사에 출연한 후 개발자들을 넘어서 범 국민적인 유명인사가 되었으니 개발자 행사에 초청되는건 당연하겠지.

뭐.. 작년 행사에서도 연사를 하셨으니깐.^^

이번에 행사를 들으면서 역시 철학이 있고 멋있는 사람이라는 생각이 들었다.

특히 전망이 아닌 자신이 하고 싶은 것을 해야한다는 말.>^^

생각해 보면 누구나 쉽게 할 수 있으면서도 쉽게 할 수 없는 그런 말 이다.

안철수 씨 ( 이젠 교수님이 익숙해질 법도 한데..) 이기 때문에 공감이 가고 믿음이 드는거 아닌가 싶다.

생각해 보면 IT쪽에는 안철수 교수님 만큼이나 존경 받을 만한 사람이 있다.

박대연 교수 ( 흠... 사실 이제 박대연 교수가 아닌 박대연 회장이라 불러야 하는데..^^ )

본인이 살아왔던 인생 스토리나 지금까지 해 왔던 업적을 그냥 무시하기에는 너무 대단한 인생과 결과를 보여왔다.

어쩌면 약간은 로얄층에 가까운 안철수 교수님 ( 사실 우리나라 제일의 학교의 제일의 학과인 서울대 의대를 들어가서 다녔고 개인적인 관심으로 그 힘든 백신까지 스스로 만들어 내신 분 ) 보다는 고등학교 졸업하고 직장생활하다가 30대 중반에 본인의 꿈을 쫓아 유학을 통해 지금 자리에 선 박대연 회장이 우리에게는 더 현실적일 수 있다는 생각이 든다.

하지만 지금 안철수 교수님과 박대연 회장님의 선 자리를 보면 너무나 큰 아쉬움이 든다.

IT인들 뿐 아닌 국민적 추앙을 한몸에 받는 안철수 교수님에 비해

국산 윈도우 이벤트 발표회도 IT계의 황우석이라는 얘기를 들어야 하는 박대연회장을 보면
참 뭐랄까...

어쩌면 우리는 심정적으로는 박대연 회장을 응원해야 .. 아님 응원하고 있는지도 모른다.

우리와 너무도 가까운 어쩌면 우리 자신일 수 있는 사람이기 떄문에

하지만 그런 애정을 가질 수 있는 사람이기 때문에

우리는 그 사람에 대해 실망하고 질책 하는 것일 지도 모른다.

사실 박대연 회장이 지금까지 회사를 키워 왔던 횡보들은 우리 나라 대부분의 대기업들이 지금의 자리에 오면서 해왔던 것들과 다를바가 없다.
하지만 우리는 지금 삼성과 LG는 우러러 보면서 ( 물론 나 처럼 안 그런 사람도 있지만...^^ 야구만 뺀다면-.-) 티맥스에 대해서는 너무 냉혹한 잣대로만 대하는 건 아닐까 싶다.

그리고 박대연 회장 스스로에게는 더 큰 문제가 있어 보인다.
미들웨어의 국산화 만으로도 박대연 회장은 충분히 존경받을 인물이다.
JEUS의 개발만으로도 티맥스는 충분히 대단한 회사임에는 틀림 없다.
하지만 왜 일지 모르는 강박관념 때문인지 너무도 큰 무리수를 두고 있다.

우리나라 IT를 위해서라는 명제로는 도저히 이해 할 수 없는 행보를 보이고 있는 것 갔다.
어쩌면 우리나라 전체 IT를 볼모로 본인의 야망을 꿈꾸는 건 아닐 까 싶다.

부디 박대연 회장님의 현명한 판단과 행볼르 기대해 본다.
( 티맥스 윈도는 과연 나오기는 하는 걸까.-.-)

'개발자세상' 카테고리의 다른 글

강사의 조건  (1) 2009.10.22
Streaming Protocol  (0) 2009.10.06
LDAP Query  (0) 2009.09.08
Spring Security 와 Active Directory 연동 -2  (0) 2009.09.01
Spring Security 와 Active Directory 연동  (0) 2009.09.01
Posted by headiron
,
지난 토요일날 아트하우스 모모에서 "타인의 취향"을 보았다.

시네큐브 걸작 10선 중 하나로 상영했는데

예전에 시네큐브 최고의 인기작이라는 명성에 보게 되었는데

다양한 사연의 사랑 얘기를 유쾌하게 담아 낸 영화 였다.

"잃어 버린 아이들의 도시" 이후 처음으로 도전하는 프랑스 영화 였는데

너무 어려운 영화 였기에 그 다음에 프랑스 영화를 도전하기가 너무 힘들었다.

사실 이 영화도 너무 깊게 생각하지 않으면 유쾌하게 볼수 있는 영화 인데도

프랑스 영화 특유의 선입견 때문에 뭔가를 찾으려 하지 않았나 싶다.

실제 영화관에서 나온 데 사람들이

이 영화가 어떤 교훈을 주려는 영화 냐는 얘기가 들린다.^^

그냥 사랑에 대해서 서로가 생각하는 고민하는 발전하는 깊이가 다름을 보여주려 했다고만 생각하면 되지 않을까..

어차피 그런 모습들 하나하나가 서로의 사랑을 만나가는 결실을 맺어 가는 모습이 아닐까..

마지막에 장면의 합주 장면과 중간 중간에 나오는 서투른 운전수의 "플룻" 연습 모습은 아직도 잘 이해가 가지는 않는다...

하지만 그 모습도 사랑의 한 모습으로 본다면 서투른 사랑도 다양한 사랑 모습 속에서 아름답게 보일 수 있다고 해석 할 수 있지 않을까?

ㅋㅋㅋ 어쩃든 프랑스 영화는...^^

'사는이야기 > 영화이야기' 카테고리의 다른 글

트랜스포머 iMax  (0) 2009.11.01
아내가 결혼했다.  (0) 2009.10.03
[영화] 타인의 삶  (0) 2009.09.05
굿바이 큐브 웰컴 투 모모  (0) 2009.08.31
벤자민 버튼의 시간의 거꾸로 간다.  (0) 2009.02.22
Posted by headiron
,
원래 계획 대로라면 다음주에 지리산의 칠선 계곡을 갈 예정이었는데

우이령 갔다가 송과장님 , 정미 누나랑 막걸리 먹고 취했을 때 다친 발목이 낳지 않아 결국 예약 했던 탐방예약, 산장 예약을 모두 취소하고 말았다.

지난 여름에 중간에 내려와서 더 가고 싶었는데 결국은 이렇게 되버리다니...-.-

우이령과  아니 막걸리 8동이와 칠선 계곡을 바꿔 버렸다.-.-
Posted by headiron
,

가락동 소프트웨어 진흥원 ( 기관 통합 되면서 이름이 바뀌었던데 모르겠다.-.-) 뒤의 성원 상떼빌 건물 1층에 있는 집인데 숨어 있는 맛집이다.

kosta 교육 받으면서 건물에 주차가 안되 어쩔 수 없이 상떼빌에 주차 했는데 주차 하고 나오는 길에 "낙지 김밥"이라는 메뉴가 너무 눈에 띄어 가서 먹어 보았는데 ...
"호. 이렇게 맛있을 수가>.^^" 감탄이 절로 났다.

뭐... 일반 분식점 형태의 가게 이고 메뉴도 "낙지김밥","낙지 라면","낙지떡짐","낙지 볶음밥" 이렇게 있지만 , 그 맛은 정말 훌륭했다.

특히 떡찜 이나 볶음밥에 사용되는 양념 소스가 정말 맛이있었다
정미 누나는 떡찜이 더 맛있다는데... 난 밥 스타일이라 "낙지 볶음밥"이 괜찮았다.

강의 들으면서 중간에 나와서 가서 먹을 때 마다 정미누나가 우리 이거 차리자고 한다.

사장님도 지금은 이집 하나지만 "동백"에 2호 점을 준비 중에 있고 자신의 기도 제목은 이 체인점을 전국에 300개 정도 오픈하고 싶으시단다.

맛 만 놓고 따지면 유정 낙지 못지 않고 ( 내 입 맛에는 훨씬 좋은 것 같다.) 분식 스타일의 메뉴다 보니 가격도 싼 편이다.
정미 누나는 특히 낙지 상태가 너무 좋아서 특히 좋다고 하신다.
( 가락시장이 가까워서 그런가..^^ )

사장님하고 얘기 하다 보니 원래 낙지 요리 가계를 했었고 블로그를 운영하다가 메뉴를 개발했다고 한다.

"낙지 김밥"은 충무 김밥 스타일로 나오는데 오징어 볶음 대신 "낙지 볶음"과 콩나물이 나온다고 생각하면 된다.
( 처음에 이 맛에 받해서 일주일 내내 이집에 오게 됐다.)
"낙지 떡찜"은 낙지를 넣은 떡볶이 라고 보면 되는데
먹고 나면 소스가 너무 맛있어서 남은 소스에 밥 말아 먹고 싶은 생각이 든다.

사장님이 운영한다는 블로그가 궁금했는데 명함에 떡 하니 주소가 있다.
가보니 블로그도 각종 요리를 깔끔하게 정리 해 놓으셨다.
블로그 보고 한 번 요리를 도전해 볼까 생각중이다.
( 개인 적으로는 물회가 땡긴다는^^)

블로그 http://blog.naver.com/woogee6
가게 주소 : 송파구 가락동80 성원 상떼빌 101동 106호
( 주차장 입구 옆의 상가 들어가는 입구 안쪽에 있다.)
가게 전화 : 431-5949 ,
사장님 손전화 : 공일일-이칠구-이팔공일

이런 맛있는 집이 성공해야 하는데.^^

'사는이야기 > 요리세계' 카테고리의 다른 글

Global Entry, CM 치킨  (0) 2022.03.28
Fogo de Chao  (0) 2022.01.10
Philadelphia restaurant week at Le Bec-Fin  (0) 2012.01.23
2012 Winder Ambler Restaurant Week  (1) 2012.01.19
봉피양에 가다  (0) 2009.10.01
Posted by headiron
,

LDAP Query

개발자세상 2009. 9. 8. 09:52
Spring Security와 LDAP 연동시 LDAP Query를 사용하게 되어 몇가지 Query를 정리해 본다.

- AD에서 LDAP Query 테스트 방법  : 
   1. "Active Directory 사용자 및 컴퓨터" Tool에서 Domain을 선택 후 ( 하위 메뉴에서도 가능 ) 오른쪽 마우스를 클릭하여 "찾기" 메뉴를 클릭
   2. "사용자,연락처, 그룹 찾기" 창이 팝업 메뉴로 출력
   3. 찾기 메뉴에서 "사용자 지정 검색" 선택
   4. "고급" 탭을 클릭하면 "LDAP 쿼리 입력" TextBox가 나오며 LDAP Query 입력 후 "지금 찾기"를 클릭하면 LDAP Query를 테스트 할 수 있다.
   5. "보기" 메뉴의 "열 선택..." 메뉴를 클릭하면 검색 결과 창에 나오는 필드를 선택할 수 있으며 "X500 고유 이름" 을 추가하면 LDAP 고유 값을 확인할 수 있다.

- LDAP 문법
   & : AND , | : OR 조건이며 
   ()를 기준으로 묶어 가며 AND OR를 적용한다.

- LDAP Filter Query 
  1. 특정 ID의 사용자 검색
      - (&(sAMAccountName={0})(objectclass=user))
        AD 의 사용자 로그인 이름이 {0} ( 위 값은 Spring Security에서 입력된 ID 값으로 대체 됨 )인 사용자를 검색
  2. 특정 ID이며 특정 그룹에 속하는 사용자 검색
      - (&(sAMAccountName={0})(|(memberOf=CN=B3 Approval,CN=Users,DC=dev,DC=247realmedia,DC=local)(memberOf=CN=B3 Reader,CN=Users,DC=dev,DC=247realmedia,DC=local)))
        memberOf 는 특정 Group의 멤버 여부를 체크한다. 따라서 위의 문법은 B3 Approval 이나 B3 Reader Group의 member이며 sAMAccountName ( AD의 사용자 로그인 이름 ) 이 {0}인 사용자를 검색한다.
Posted by headiron
,
송과장님이 같이 등반 어떻냐고 해서 둘이서 우이령 고개를 다녀왔다.

같이 괜찮은데 가보자고 하니... 제일 먼저 생각난게 우이령 고개였다.

40년 넘게 통제 하고 있다가 개방을 했으니 회손이 덜 되어 있지 않을 까 하는 생각이었다.

인터넷으로 가는 길 확인하고 일요일 아침에 구파발에 도착해보니..

헉... 사람들이 줄 지어서 버스를 기다린다.

"석굴암 입구" 가는 버스는 그냥 타도 되냐고 하니 "석굴암"가는 버스가 모두 북한산 입구를 가기 때문에 그냥 북한산 버스 타고 가서 입구에서 다시 "석굴암" 가는 버스를 타라 한다.

등산 하시는 분들이 많은 건 알았지만 이렇게 많을 줄이야.-.-

어쨋든 북한산 입구에서 부터 등반객들 내리기 시작하고 "우이령 고개" 도착할 때 쯤 까지 몇 명이 남아 있기에 저 분들도 "우이령"가시나 보다 했더니... 아무도 안 내리고 송과장님과 나만 내린다.

조금 당황 하기는 했지만 그래도 뭐 호젓하고 좋네..

등산로 주위로 군 부대와 사격장이 위치하여 있어서 아직 입산 통제했던 분위기는 들었지만 우이령 고개에 가까와 질수록 호젓하고 주위에 회손 된 흔적도 없고 하니 보기도 좋다.

주위로 보이는 고개들 마다 저기는 어딜까 하는 생각을 하는 것도 재미있다.

우이령 고개에서 내려오는 길에 전경 부대가 보이니 거기 있는 애들이 너무 부러워 보인다.

이 좋은 환경을 누리고 있으니.. 뭐.. 하긴 이 좋은 환경이라는 건 우리 처럼 가끔 가는 사람에게만 보일 지 모른다.

전체적으로 등산 코스는 4km 남짓 되어 등산 보다는 산책 이라고 봐도 무방하다.

사람들도 그런 생각인지 곳곳에 "막걸리" 한잔씩 하시는 분들이 보인다.

그걸 보니 또 어찌나 막걸리가 땡기는 지 우이동 내려와서 정미 누나 불러다가 막걸리 잔치를 벌였다. ( 세명이서 8개를 먹었더니 다음날 해장음식이 간절했다.^^ )

또 내려오는 길에 벌써 빨갛게 물든 단풍 잎이 보인다.
그걸 보니 올 가을에 멀리 단풍 구경 가서 고생하느니 차라리 우이령 고개와서 구경하는 게 좋을 듯 싶다.

오랜만에 다른 사람과 등산하는 느낌이 참 좋다.
특히 걸으면서 이런 저런 얘기를 해 보니 자연이나 산을 좋아하는 모습이 나랑 잘 맞는 다는 느낌이다.
또 이런 저런 다큐를 보셨던 얘기를 해 주시는데,
정말 박학다식 하다는 느낌이 들고 또 정말 이런 자연을 사랑한다는 느낌이 강하게 든다.
나도 자연을 좋아한다면서 다큐 같은 건 전혀 안보는데.-.-
좋아 한다는 말 보다도 그런 지식을 쌓는 것이 더 좋을 것 같다.

어쨋든 너무 좋은 곳을 알게 되어 기분이 좋고
또 좋은 사람과 좋은 경험을 하게 되어 좋다.
특히 앞으로 다양한 산을 함께 다닐 수 있을 것 같아 더 기분이 좋다.

그나저나 술 취해서 집에 오다가 접질린 발목이 빨리 낳아야 다다음주 휴가를 갈 수 있을 텐데...



'사는이야기 > 등반정보' 카테고리의 다른 글

오대산 소금강 등반 사진  (0) 2009.12.01
지리산 종주 실패기  (0) 2009.08.16
한라산 백록담 정상  (0) 2009.05.27
한라산 등반사진  (0) 2009.05.26
백운대에 올라...  (0) 2009.05.09
Posted by headiron
,
전에 부터 제목은 익히 들어왔지만 볼 기회가 없었는데..

불행인지 다행인지 "굿바이 큐브, 웰컴 두 모모" 행사 중 "큐브 상영 명작 10선" 에 타인의 삶이 있기에 보게 되었다.

사실 영화에 대한 설레임도 있었지만 처음으로 ( 생각해 보니 원경이 대학 원서 낸다고 이대 한번 들어갔었던 기억이^^) 여대를 가다 보니 뻘쭘 할 줄 알았는데
왠걸.... 많은 남자들이 꺼리낌 없이 들어간다는.>^^

영화 줄거리는 철두 철미한 비밀 경찰의 삶을 살아가던 주인공이 연극 시나리오 작가를 감시하다가 그에 동화되어 가 결국 그를 보호해주는 내용이다.

마지막에 본인의 삶을 위해 그렇게 사랑하던 애인을 배반하는 배우와 자신의 삶을 내걸고 그를 지켜내는 주인공의 모습이 대비된다.

통일이후 우연히 극장에서 예전에 자신의 애인을 뺏으려 했던 장관의 모습을 본 작가가 본인을 감시하던 사람이 있었음을 알게 되어 통일전 자료를 뒤지다가 자신을 보호해준 사람의 존재를 알고 통일 후 놓았던 펜을 들어 그에게 헌정하는 책을 만들어 내는 내용이다.

사실 통일 후 장관을 만나는 장면에서 통일이후에도 멀쩡해 보이는 장관의 모습을 보면서 왠지 모를 분노와 우리의 상황이 대비되었는데 이야기의 고리를 만들어 내기 위한 하나의 단서라는 생각을 하니 편안할 수 있었다.

마지막에 작가가 주인공을 찾았으면서도 그를 지나쳐 가는 장면에서는 왜 저래야 할 까 하는 생각이 들었는데

결국 다시 작품 활동을 하며 책 표지에 주인공에 대한 헌사의 글을 남김으로 해서 자신을 지켜주기 위해 본인의 삶을 버린 주인공을 위해 펜을 드는 것이 오히려 더 큰 보답이라는 메시지를 보여주었다.

처음 보는 독일 영화 였지만 영화 내내 들리는 은은한 음악... 절제된 영상등 정말 보기 드문 수작이었다.

너무 궁금해서 영화 종료 후 예매석에 가보니 2007년 아카데미 외국어 작품상을 수상했단다.


처음가는 모모였는데 솔직히 너무 협소한 극장 공간에 좀 실망을 했다.

특히 영화 보기에 최적의 환경이었던 시네큐브와 비교하면 특히 아쉬웠다.

하지만 그래도 이렇게 훌륭한 영화를 감상할 수 있는 공간이 서울 안에 남아 있다는 것에 위안을 삼고 싶다.

'사는이야기 > 영화이야기' 카테고리의 다른 글

아내가 결혼했다.  (0) 2009.10.03
타인이 취향  (0) 2009.09.16
굿바이 큐브 웰컴 투 모모  (0) 2009.08.31
벤자민 버튼의 시간의 거꾸로 간다.  (0) 2009.02.22
발키리를 보고.  (0) 2009.02.01
Posted by headiron
,
인터넷을 뒤지다 보니 Spring Security와 Active Directory를 연동하는 또 다른 방식이 있다.

이 방식은 Customize된 Authentication Class를 생성해야 하는 단점이 있다.

하지만 반대로 우리와 같이 LDAP 연동시 Authorization 관련 로직을 Customize 할 때 쉬울 듯 하다.( 뭐 아직은 해보지 않은 상태 지만 내부 코드를 보면 Role 명을 쉽게 입력할 수 있을 것 같다. )

그리고 인증 방식은 LDAP 형태가 아닌 Computer Name\사용자 계정 형태이다.
( 이 부분이 AD가 아닌 Window 내부 사용자 계정 관리 방식으로 보여 조금 꺼림직 하다. )

하지만 관리자 계정 정보를 필요로 하지 않는 다는 엄청난(?) 장점이 있다.

출처 : http://stackoverflow.com/questions/84680/how-do-you-authenticate-against-an-active-directory-server-using-spring-security 첫번째 댓글

[Spring Security Config]
<beans:bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
       
<beans:constructor-arg value="ldap://hostname.queso.com:389/" />
</beans:bean>

<beans:bean id="ldapAuthenticationProvider" class="org.queso.ad.service.authentication.LdapAuthenticationProvider">
       
<beans:property name="authenticator" ref="ldapAuthenticator" />
       
<custom-authentication-provider />
</beans:bean>

<beans:bean id="ldapAuthenticator" class="org.queso.ad.service.authentication.LdapAuthenticatorImpl">
       
<beans:property name="contextFactory" ref="contextSource" />
       
<beans:property name="principalPrefix" value="QUESO\" />
</beans:bean>

위 내용 중 principalPrefix는 Computuer 명 을 넣으면 된다.
즉 인증시 "컴퓨터명\사용자ID"가 LDAP 서버로 전달된다.

[LdapAuthenticationProvider.java]
/**
 * Custom Spring Security authentication provider which tries to bind to an LDAP server with
 * the passed-in credentials; of note, when used with the custom {@link LdapAuthenticatorImpl},
 * does <strong>not</strong> require an LDAP username and password for initial binding.
 *
 * @author Jason
 */
public class LdapAuthenticationProvider implements AuthenticationProvider {
private LdapAuthenticator authenticator;

       
public Authentication authenticate(Authentication auth) throws AuthenticationException {

               
// Authenticate, using the passed-in credentials.
               
DirContextOperations authAdapter = authenticator.authenticate(auth);

               
// Creating an LdapAuthenticationToken (rather than using the existing Authentication
               
// object) allows us to add the already-created LDAP context for our app to use later.
               
LdapAuthenticationToken ldapAuth = new LdapAuthenticationToken(auth, "ROLE_USER");
               
InitialLdapContext ldapContext = (InitialLdapContext) authAdapter
                               
.getObjectAttribute("ldapContext");
               
if (ldapContext != null) {
                        ldapAuth
.setContext(ldapContext);
               
}

               
return ldapAuth;
       
}

       
public boolean supports(Class clazz) {
               
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(clazz));
       
}

       
public LdapAuthenticator getAuthenticator() {
               
return authenticator;
       
}

       
public void setAuthenticator(LdapAuthenticator authenticator) {
               
this.authenticator = authenticator;
       
}
}
[LdapAuthenticatorImpl.java]
/**
 * Custom Spring Security LDAP authenticator which tries to bind to an LDAP server using the
 * passed-in credentials; does <strong>not</strong> require "master" credentials for an
 * initial bind prior to searching for the passed-in username.
 *
 * @author Jason
 */

public class LdapAuthenticatorImpl implements LdapAuthenticator {

       
private DefaultSpringSecurityContextSource contextFactory;
       
private String principalPrefix = "";

       
public DirContextOperations authenticate(Authentication authentication) {

               
// Grab the username and password out of the authentication object.
               
String principal = principalPrefix + authentication.getName();
               
String password = "";
               
if (authentication.getCredentials() != null) {
                        password
= authentication.getCredentials().toString();
               
}

               
// If we have a valid username and password, try to authenticate.
               
if (!("".equals(principal.trim())) && !("".equals(password.trim()))) {
                       
InitialLdapContext ldapContext = (InitialLdapContext) contextFactory
                                       
.getReadWriteContext(principal, password);

                       
// We need to pass the context back out, so that the auth provider can add it to the
                       
// Authentication object.
                       
DirContextOperations authAdapter = new DirContextAdapter();
                        authAdapter
.addAttributeValue("ldapContext", ldapContext);

                       
return authAdapter;
               
} else {
                       
throw new BadCredentialsException("Blank username and/or password!");
               
}
       
}

       
/**
         * Since the InitialLdapContext that's stored as a property of an LdapAuthenticationToken is
         * transient (because it isn't Serializable), we need some way to recreate the
         * InitialLdapContext if it's null (e.g., if the LdapAuthenticationToken has been serialized
         * and deserialized). This is that mechanism.
         *
         * @param authenticator
         *          the LdapAuthenticator instance from your application's context
         * @param auth
         *          the LdapAuthenticationToken in which to recreate the InitialLdapContext
         * @return
         */

       
static public InitialLdapContext recreateLdapContext(LdapAuthenticator authenticator,
                       
LdapAuthenticationToken auth) {
               
DirContextOperations authAdapter = authenticator.authenticate(auth);
               
InitialLdapContext context = (InitialLdapContext) authAdapter
                               
.getObjectAttribute("ldapContext");
                auth
.setContext(context);
               
return context;
       
}

       
public DefaultSpringSecurityContextSource getContextFactory() {
               
return contextFactory;
       
}

       
/**
         * Set the context factory to use for generating a new LDAP context.
         *
         * @param contextFactory
         */

       
public void setContextFactory(DefaultSpringSecurityContextSource contextFactory) {
               
this.contextFactory = contextFactory;
       
}

       
public String getPrincipalPrefix() {
               
return principalPrefix;
       
}

       
/**
         * Set the string to be prepended to all principal names prior to attempting authentication
         * against the LDAP server.  (For example, if the Active Directory wants the domain-name-plus
         * backslash prepended, use this.)
         *
         * @param principalPrefix
         */

       
public void setPrincipalPrefix(String principalPrefix) {
               
if (principalPrefix != null) {
                       
this.principalPrefix = principalPrefix;
               
} else {
                       
this.principalPrefix = "";
               
}
       
}

}

[LdapAuthenticationToken.java]
/**
 * <p>
 * Authentication token to use when an app needs further access to the LDAP context used to
 * authenticate the user.
 * </p>
 *
 * <p>
 * When this is the Authentication object stored in the Spring Security context, an application
 * can retrieve the current LDAP context thusly:
 * </p>
 *
 * <pre>
 * LdapAuthenticationToken ldapAuth = (LdapAuthenticationToken) SecurityContextHolder
 *              .getContext().getAuthentication();
 * InitialLdapContext ldapContext = ldapAuth.getContext();
 * </pre>
 *
 * @author Jason
 *
 */

public class LdapAuthenticationToken extends AbstractAuthenticationToken {

       
private static final long serialVersionUID = -5040340622950665401L;

       
private Authentication auth;
       
transient private InitialLdapContext context;
       
private List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

       
/**
         * Construct a new LdapAuthenticationToken, using an existing Authentication object and
         * granting all users a default authority.
         *
         * @param auth
         * @param defaultAuthority
         */

       
public LdapAuthenticationToken(Authentication auth, GrantedAuthority defaultAuthority) {
               
this.auth = auth;
               
if (auth.getAuthorities() != null) {
                       
this.authorities.addAll(Arrays.asList(auth.getAuthorities()));
               
}
               
if (defaultAuthority != null) {
                       
this.authorities.add(defaultAuthority);
               
}
               
super.setAuthenticated(true);
       
}

       
/**
         * Construct a new LdapAuthenticationToken, using an existing Authentication object and
         * granting all users a default authority.
         *
         * @param auth
         * @param defaultAuthority
         */

       
public LdapAuthenticationToken(Authentication auth, String defaultAuthority) {
               
this(auth, new GrantedAuthorityImpl(defaultAuthority));
       
}

       
public GrantedAuthority[] getAuthorities() {
               
GrantedAuthority[] authoritiesArray = this.authorities.toArray(new GrantedAuthority[0]);
               
return authoritiesArray;
       
}

       
public void addAuthority(GrantedAuthority authority) {
               
this.authorities.add(authority);
       
}

       
public Object getCredentials() {
               
return auth.getCredentials();
       
}

       
public Object getPrincipal() {
               
return auth.getPrincipal();
       
}

       
/**
         * Retrieve the LDAP context attached to this user's authentication object.
         *
         * @return the LDAP context
         */

       
public InitialLdapContext getContext() {
               
return context;
       
}

       
/**
         * Attach an LDAP context to this user's authentication object.
         *
         * @param context
         *          the LDAP context
         */

       
public void setContext(InitialLdapContext context) {
               
this.context = context;
       
}

}


'개발자세상' 카테고리의 다른 글

박대연, 그리고 안철수  (1) 2009.09.24
LDAP Query  (0) 2009.09.08
Spring Security 와 Active Directory 연동  (0) 2009.09.01
UML 2.0 과 유스케이스 강의를 듣고  (0) 2009.08.28
RPM 관련 명령  (0) 2009.08.18
Posted by headiron
,

B3 관련하여 본사 AD와 연동을 위해 Spring Security와 AD연동을 테스트 해 보았다.

아래와 같이 spring 설정을 하게 되면 Spring Security는 잘 동작 한다.

이 경우 인증 뿐만 아니라 AD의 그룹기능을 이용하여 Spring Security의 Role도 연동할 수 있게 된다. ( DefaultLdapAuthoritiesPopulator class의 "rolePrefix" 부분을 설정하면 AD의 그룹명 앞에 Prefix를 붙여서 작업할 수 있다. )

하지만 이 경우의 문제점은 AD의 관리자 권한을 가지고 있어야만 된다는 것이다.

여러 모로 생각해 보아도 우리에게 AD 관리자 권한을 열어 줄리는 만무한데...-.-

아래 내용은 http://maniezhilan.blogspot.com/2008/10/spring-security-204-with-active.html 에서 퍼왔음.

[applicationContext-security.xml]
 
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:s="http://www.springframework.org/schema/security"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
 http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
 <s:http>
         <s:intercept-url pattern="/secure/extreme/**" access="ROLE_eCommunications"/>
         <s:intercept-url pattern="/secure/**" access="IS_AUTHENTICATED_REMEMBERED"/>
         <s:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
         <s:form-login/>
         <s:anonymous/>
         <s:logout/>
 </s:http>
 <bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
  <constructor-arg value="ldap://192.168.192.71:3268/DC=dev,DC=247realmedia,DC=co,DC=kr?sAMAccountName?sub?(objectClass=*)"/>
  <property name="userDn" value="CN=kim ducheol,CN=Users,DC=dev,DC=247realmedia,DC=co,DC=kr"/>
  <property name="password" value="XXXXXXX"/>
 </bean>
 <bean id="secondLdapProvider" class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
  <s:custom-authentication-provider />
  <constructor-arg>
   <bean class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
    <constructor-arg ref="contextSource"/>
    <property name="userSearch">
     <bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
      <constructor-arg index="0" value=""/>
      <constructor-arg index="1" value="(&amp;(sAMAccountName={0})(objectclass=user))"/>
      <constructor-arg index="2" ref="contextSource" />
     </bean>    
    </property>
   </bean>
  </constructor-arg>
  <constructor-arg>
   <bean class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
    <constructor-arg ref="contextSource" />
    <constructor-arg value="" />
    <property name="rolePrefix" value="ROLE_"/>
    <property name="searchSubtree" value="true"/>
    <property name="convertToUpperCase" value="false"/>
   </bean>
  </constructor-arg>
 </bean>
</beans>

'개발자세상' 카테고리의 다른 글

LDAP Query  (0) 2009.09.08
Spring Security 와 Active Directory 연동 -2  (0) 2009.09.01
UML 2.0 과 유스케이스 강의를 듣고  (0) 2009.08.28
RPM 관련 명령  (0) 2009.08.18
kernel ARG_MAX 값  (0) 2009.05.08
Posted by headiron
,