개요
프로젝트를 진행하면서, Azure Outlook & Sharepoint 연동을 다루게 되어 추후 별도의 Connector로 사용될 수 있도록 코드를 정리하였습니다. GPT를 사용하면 가이드를 잘 알려주지만, 생각보다 Connect 하기 전에 설정해야할 것들이 많이 있어서 빠르게 연동하는데는 어려움이 있었습니다.
0. 사전 요구 사항
- Azure Portal (https://azure.microsoft.com/) 회원 가입
- M365 Outlook과 Sharepoint의 경우, Azure 기반으로 되어있기 때문에 Azure Portal에 먼저 가입하는 것이 필요합니다.
- M365에 대한 라이선스 구매 후, 계정에 할당하기
- M365 라이센스가 없으면, 권한 작업을 진행해도 정상적으로 Outlook Mail 연동이 불가능합니다.
- M365 관리 센터(https://admin.microsoft.com/ ) 접속하여, 관리 포털로 이동
- "홈" 메뉴의 "사용자 목록"에서 생성한 계정이름을 클릭하여, 계정 상세화면으로 이동
- "라이선스 및 앱" 탭에서 "라이선스" 영역에서 "Microsoft 365 Business Basic" 체크 후, "변경 내용 저장" 클릭
- 생성한 계정으로, https://m365.cloud.microsoft/ 에 로그인 후, "앱" 항목에서, "Outlook" 또는 "Sharepoint" 접속 시 정상적으로 화면으로 접속되어야 합니다. (라이선스가 없으면 사서함이 생성되지 않습니다.)
1. Azure Console에서 접근 권한 설정하기
- "Entra ID"(https://portal.azure.com/#view/Microsoft_AAD_IAM)서비스 접속 후, 권한 설정하기
- Microsoft Entra ID는 외부 리소스에 액세스하는 데 사용할 수 있는 클라우드 기반 ID 및 액세스 관리 서비스입니다. 액세스 정보(Tenant_id, Client_id, Client_secret)를 얻기 위해, Entra ID에서 설정이 필요합니다.
- Azure Portal에서 "Entra ID" 검색 후 이동
- 좌측 메뉴 중 "관리" 메뉴 하위의 "앱 등록" 클릭하여, 앱 목록 화면으로 이동
- 상단 메뉴 중 "+ 새 등록" 클릭 후 앱 등록 화면 이동
- 이름 : <프로젝트 명칭>(추후 변경 가능)
- 지원되는 계정 유형 : "모든 조직 디렉터리의 계정(다중 테넌트, 개인 Microsoft 계정)"
- "등록" 버튼 클릭
- "앱 등록" 목록 화면에서, 위에서 생성한 "앱 이름"을 클릭하여, 앱 상세 화면 이동
(앱 목록이 보이지 않으면, "모든 어플리케이션" 탭을 선택해주세요.)- 좌측 메뉴 중 "관리" 메뉴 하위의 "인증서 및 암호" 클릭하여, 인증서 및 암호 설정 화면으로 이동
- "클라이언트 비밀" 탭으로 이동
- "+ 새 클라이언트 암호" 버튼을 클릭하여, 클라이언트 시크릿 키 생성 화면 이동
- 설명 : 암호 키에 대한 설명
- "추가" 버튼 클릭
- 목록 화면에서 아래 항목 복사 (이 때 복사 못하면, 재생성해야합니다.)
- "값" 항목 : client_secret_key로 사용됩니다.
- 좌측 메뉴 중 "관리" 메뉴 하위의 "API 사용 권한" 클릭하여, API 권한 설정 화면으로 이동
- "+ 권한 추가" 버튼을 클릭하여, 아래 Outlook 관련 권한을 추가
- "Microsoft Graph" - "애플리케이션 사용 권한" 선택
- 권한 선택 검색창에서 "Mail" 검색
- 검색 결과 항목 모두 Check
(추후에는 필요 없는 항목은 제거해야 합니다.)
- 검색 결과 항목 모두 Check
- 권한 선택 검색창에서 "User" 검색
- "User.Read.All" 권한 추가
- "권한 추가" 버튼을 클릭하여 추가
- 권한 선택 검색창에서 "Mail" 검색
- "Microsoft Graph" - "애플리케이션 사용 권한" 선택
- "+ 권한 추가" 버튼을 클릭하여, 아래 Sharepoint 관련 권한을 추가
- "Microsoft Graph" - "애플리케이션 사용 권한" 선택
- "Files.Read.All" 권한 추가
- "Sites.Read.All" 권한 추가
- "User.Read.All" 권한 추가
- "SharePoint" - "애플리케이션 사용 권한" 선택
- "Sites.FullControl.All" 권한 추가
- "Sites.Manage.All" 권한 추가
- "Sites.Read.All" 권한 추가
- "Sites.ReadWrite.All" 권한 추가
- "Sites.Selected" 권한 추가
- "Sites.FullControl.All" 권한 추가
- "권한 추가" 버튼을 클릭하여 추가
- "Microsoft Graph" - "애플리케이션 사용 권한" 선택
- "+ 권한 추가" 버튼 옆에, "OOO에 대한 관리자 동의 허용" 버튼을 클릭
(위에서 할당한 권한 중에, 관리자 동의가 필요한 권한이 있으므로 해당 버튼을 통해 허용해주어야 한다.)
- "+ 권한 추가" 버튼을 클릭하여, 아래 Outlook 관련 권한을 추가
- 좌측 메뉴 중 첫번째 항목인 "개요"를 클릭하여, 아래 항목을 모두 복사합니다.
- "애플리케이션(클라이언트) ID" 항목 : client_id로 사용됩니다.
- "디렉터리(테넌트) ID" 항목 : tenant_id로 사용됩니다.
- 좌측 메뉴 중 "관리" 메뉴 하위의 "인증서 및 암호" 클릭하여, 인증서 및 암호 설정 화면으로 이동
- 여기까지 수행하셨다면, 위에서 복사한 client_secret_key와 client_id, tenant_id로 MS가 제공하는 Graph API를 통해 접속이 가능합니다.
2. M365 Outlook & Sharepoint Connector 샘플 코드
msal 라이브러리를 통해 권한 인증을 수행하고, token값을 이용해 Graph API에 request하는 방식으로 Connection이 이루어집니다.
로컬에서 환경변수를 용이하게 관리하기 위한 dotenv 라이브러리와 API 요청 처리를 위한 requests 라이브러리가 사용되었습니다.
# .env 파일
TENANT_ID=<Entra ID 앱 개요 화면에서 복사한 tenant_id>
CLIENT_ID=<Entra ID 앱 개요 화면에서 복사한 client_id>
CLIENT_SECRET=<Entra ID 앱 인증서 화면에서 복사한 client_secret_key>
USER_EMAIL=<생성한 Azure 메일 주소>
# sharepoint.com 다음에 반드시 ":"을 넣어주셔야 합니다..
SITE_URL=<m365테넌트명>.sharepoint.com:/sites/<sharepoint에서 생성한 site명>
import msal
import requests
import os
import dotenv
dotenv.load_dotenv()
CLIENT_ID = os.getenv("CLIENT_ID")
TENANT_ID = os.getenv("TENANT_ID")
CLIENT_SECRET = os.getenv("CLIENT_SECRET")
AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}"
SCOPES = ["https://graph.microsoft.com/.default"]
USER_EMAIL = os.getenv("USER_EMAIL")
MAIL_COUNT = int(os.getenv("MAIL_COUNT", "10"))
def get_access_token():
msal_app = msal.ConfidentialClientApplication(
CLIENT_ID,
authority=AUTHORITY,
client_credential=CLIENT_SECRET
)
result = msal_app.acquire_token_for_client(SCOPES)
access_token = result["access_token"]
return access_token
def get_emails(user_email, access_token, mail_count = 10):
url = f"https://graph.microsoft.com/v1.0/users/{user_email}/messages"
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
params = {
"$top": mail_count,
"$select": "sender,subject,receivedDateTime",
"$orderby": "receivedDateTime DESC"
}
response = requests.get(url, headers=headers, params=params)
response.raise_for_status()
return response.json().get('value', [])
if __name__ == "__main__":
user_email = USER_EMAIL
access_token = get_access_token()
mails = get_emails(user_email, access_token, MAIL_COUNT)
print(mails)




최근댓글