Active Directory로 Password를 초기화하려면 LDAPS로 인증을 해야 만 한다.
Active Directory와 LDAPS(LDAP over SSL) 연결을 설정하려면 서버에 적절한 SSL 인증서가 설치되어 있고, 클라이언트에서 이 인증서를 신뢰해야 합니다. 이 과정은 다음과 같은 단계를 포함합니다:
- Active Directory 서버에서 SSL 인증서 설정
- LDAP 요청 서버에 SSL 인증서를 신뢰하도록 설정
- Streamlit 애플리케이션에서 LDAPS 연결 설정
[결과화면]
인증서 설치 하지 않은 상태 로그인 오류 화면 | 인증서 설치 후 로그인 성공 화면 |
인증서 설치 후 인증은 IP로는 되지 않고 아래처럼 서버의 FQDN으로 인증을 해야 한다.
오류 내용을 보면 인증서에 commonName으로 GSDC01.gsoft.local 이 설정되어 있고 이 이름을 제외한 서버는 인증이 되지 않는 것을 알 수 있다.
서버를 추가 하려면 인증서에 commonName에 서버를 추가하면 인증이 가능하다.
서버 이름으로 만 로그인 한 경우 오류 발생 | FQDN으로 인증한 경우 정상 인증 |
1. Active Directory 서버에서 SSL 인증서 설정
Active Directory 서버에 SSL 인증서를 설치해야 합니다. 이 인증서는 일반적으로 내부 CA(인증 기관) 또는 공개 CA에서 발급받을 수 있습니다. 인증서를 설치하고 나면, 서버에서 LDAP 서비스를 SSL(포트 636)을 통해 사용할 수 있습니다.
아래 사이트에 인증서 서비스 설치 가이드를 작성했습니다.
2. 클라이언트에서 SSL 인증서를 신뢰하도록 설정
클라이언트 머신에서 LDAP 서버의 SSL 인증서를 신뢰하도록 설정해야 합니다. 이를 위해 서버 인증서를 가져와 클라이언트의 신뢰할 수 있는 인증서 저장소에 추가해야 합니다.
아래 사이트에 신뢰할 수 있는 인증기관의 인증서 설치 가이드를 작성했습니다.
3. Streamlit 애플리케이션에서 LDAPS 연결 설정
이제 ldap3 라이브러리를 사용하여 LDAPS를 통해 Active Directory에 연결하는 Streamlit 애플리케이션을 작성할 수 있습니다. 다음 코드는 SSL 인증서를 확인하는 설정을 포함합니다.
[코드설명]
컴퓨터에 인증서를 설치 했음으로 아래와 같이 tls 설정을 한다.
ldap3 인증에 tls 사용
import ssl ssl 모듈 설정
서버에 ssl 인증 설정
Tls 설정에서 CERT_REQUIRED 설정으로 인증서 확인 후 인증처리
[소스코드]
import streamlit as st
from ldap3 import Server, Connection, ALL, SIMPLE, Tls
import ssl
def authenticate(server, username, password):
try:
# SSL/TLS로 서버 정의
tls_configuration = Tls(validate=ssl.CERT_REQUIRED, version=ssl.PROTOCOL_TLSv1_2)
server = Server(server, use_ssl=True, get_info=ALL, tls=tls_configuration)
# LDAP 서버에 연결
conn = Connection(server, user=username, password=password)
if conn.bind():
return True
else:
return False
except Exception as e:
st.error(f"인증 오류 : {str(e)}")
return False
# main Page 만들기
def main_page(server,username,password):
if st.button('로그아웃'):
st.session_state['authenticated'] = False
st.session_state['server'] = None
st.session_state['username'] = None
st.session_state['password'] = None
# 현재 상태 값을 false로 변경 후 다시 시작하여 화면을 변경함
st.rerun()
st.title('Active Directory 메인 페이지')
st.markdown(f"성공적으로 로그인했습니다.\n\n현재 로그인한 사용자: {username}")
# SSL/TLS로 서버 정의
tls_configuration = Tls(validate=ssl.CERT_REQUIRED, version=ssl.PROTOCOL_TLSv1_2)
server = Server(server, use_ssl=True, get_info=ALL, tls=tls_configuration)
# LDAP 서버에 연결
conn = Connection(server, user=username, password=password)
if conn.bind():
# 사용자 DN 가져오기
search_base = 'dc=gsoft,dc=local' # 적절한 검색 베이스 DN으로 변경
#search_filter = f'(sAMAccountName={username})'
search_filter = f'(UserPrincipalName={username})'
conn.search(search_base, search_filter, attributes=['displayName', 'description'])
if conn.entries:
entry = conn.entries[0]
st.write(f"displayname : {entry.displayName.value}" )
st.write(f"description : {entry.description.value}" )
def login_page():
# Streamlit UI
st.title('Active Directory 로그인 페이지')
username = st.text_input('로그인 ID', placeholder='id@domain.local 형식으로 입력해 주세요.')
password = st.text_input('비밀번호', type='password')
server = st.text_input('서버 이름 혹은 IP 주소')
if st.button('로그인'):
if not username:
st.error("로그인 ID를 입력하세요.")
elif not password:
st.error("비밀번호를 입력하세요.")
elif not server:
st.error("서버 이름 혹은 IP를 입력하세요.")
else:
if authenticate(server, username, password):
st.session_state['authenticated'] = True
st.session_state['server'] = server
st.session_state['username'] = username
st.session_state['password'] = password
# 현재 상태 값을 true로 변경 후 다시 시작하여 화면을 변경함
st.rerun()
else:
st.error('로그인 실패')
# 세션 상태 초기화
if 'authenticated' not in st.session_state:
st.session_state['authenticated'] = False
st.session_state['server'] = None
st.session_state['username'] = None
st.session_state['password'] = None
# 로그인 상태에 따라 페이지 표시
if st.session_state['authenticated']:
main_page(st.session_state['server'],st.session_state['username'],st.session_state['password'])
else:
login_page()
댓글