본문 바로가기
기술자료 (KB)/Active Directory (AD)

06. Streamlit AD 로그인 후 패스워드 변경

by 이완주 2024. 8. 2.

 

 

05. Streamlit으로 AD 로그인을 SSL로 인증하기

Active Directory로 Password를 초기화하려면 LDAPS로 인증을 해야 만 한다. Active Directory와 LDAPS(LDAP over SSL) 연결을 설정하려면 서버에 적절한 SSL 인증서가 설치되어 있고, 클라이언트에서 이 인증서를

leemcse.tistory.com

 

현재 로그인한 사용자가 자신의 AD 비밀번호를 변경하려고 한다.

이전 강좌의 SSL 설정이 되면 패스워드 변경이 가능해 진다.

AD 정책에 의해 패스워드 변경이 되며 관련 오류가 화면에 나타납니다.

 

 

[결과화면]

메인화면에서 버튼을 누루면   

 

[코드설명]

페이지 이동 설정

최초 사이트에 세션초기화를 하고 접속하면 로그인페이지로 연결 

 

로그인이 성공하면 Session 상태 값  page 값에 main 값 설정

 

메인 페이지 표시

 

메인 페이지에서 로그아웃을 누루면 session_state False로 상태를 login_page() 호출

 

비밀번호 변경

비밀번호 변경 버튼을 누루면 change_password_page 함수 호출

 

로그인 페이지에서 이전 버튼 설정

 

패스워드 변경 값 입력

 

비밀번호 변경 실패 오류 및 성공 설정

 

 

[소스코드]

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
        #st.session_state['page'] = 'login'  # 로그인 페이지로 전환
        # 현재 상태 값을 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}" )

    if st.button("비밀번호 변경"):
        st.session_state['page'] = 'change_password'
        st.rerun()

def change_password_page(server, username):
    
    if st.button("이전"):
        st.session_state['page'] = 'main'
        st.rerun()
    
    st.title('비밀번호 변경 페이지')

    old_password = st.text_input("현재 비밀번호", type='password')
    new_password = st.text_input("새 비밀번호", type='password')
    confirm_password = st.text_input("새 비밀번호 확인", type='password')

    if st.button("비밀번호 변경"):
        if new_password != confirm_password:
            st.error("새 비밀번호와 확인 비밀번호가 일치하지 않습니다.")
        else:
            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=old_password)
                if not conn.bind():
                    st.error("현재 비밀번호가 잘못되었습니다.")
                else:
                    # 사용자 DN 가져오기
                    search_base = 'dc=gsoft,dc=local'  # 적절한 검색 베이스 DN으로 변경
                    search_filter = f'(UserPrincipalName={username})'
                    conn.search(search_base, search_filter, attributes=['displayName'])
                    if conn.entries:
                        user_dn = conn.entries[0].entry_dn

                        # LDAP 비밀번호 변경
                        conn.extend.microsoft.modify_password(user_dn, new_password, old_password)
                        if conn.result['description'] == 'success':
                            st.success("비밀번호가 성공적으로 변경되었습니다.")
                            st.session_state['password'] = new_password
                        else:
                            st.error(f"비밀번호 변경 실패: {conn.result}")
            except Exception as e:
                st.error(f"비밀번호 변경 중 오류 발생: {str(e)}")

def login_page():
    # Streamlit UI
    st.title('Active Directory 로그인 페이지')
    
    username = st.text_input('로그인 ID', placeholder='AccountID@domain.local 형식으로 입력해 주세요.')
    password = st.text_input('비밀번호', type='password')
    server = st.text_input('서버 FQDN', placeholder='servername.domain.local 형식으로 입력해 주세요.')

    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
                st.session_state['page'] = 'main'

                # 현재 상태 값을 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']:
    if st.session_state['page'] == 'main':
        main_page(st.session_state['server'], st.session_state['username'], st.session_state['password'])
    elif st.session_state['page'] == 'change_password':
        change_password_page(st.session_state['server'], st.session_state['username'])
else:
    login_page()

 

 

 

07. Streamlit AD 프로그램 코드 분리

06. Streamlit AD 로그인 후 패스워드 변경05. Streamlit으로 AD 로그인을 SSL로 인증하기Active Directory로 Password를 초기화하려면 LDAPS로 인증을 해야 만 한다. Active Directory와 LDAPS(LDAP over SSL) 연결을 설정하

leemcse.tistory.com

 

댓글