Python 애플리케이션과 Oracle Identity Cloud Service 간의 인증에 대해 알아보기

이제 Python 웹 애플리케이션과 Oracle Identity Cloud Service 간의 인증에 대해 알아볼 수 있습니다. 여기에는 다음 사항을 이해하는 것이 포함됩니다.

  • Python 애플리케이션과 함께 SDK를 사용하여 Oracle Identity Cloud Service로 인증하는 경우가 있습니다.

  • Oracle Identity Cloud Service가 Python SDK에 대해 지원하는 3단계 인증 플로우입니다.

  • Python SDK의 방법 및 기능

3단계 인증 플로우에 대해 알아보기

Oracle Identity Cloud Service는 Python SDK에 대해 3단계 인증 플로우를 지원합니다. 이 플로우에서 사용자는 Oracle Identity Cloud Service와 직접 상호작용합니다. 사용자가 사인인한 후 Oracle Identity Cloud Service는 SDK가 사용자 액세스 토큰을 교환하는 권한 부여 코드를 발행합니다. 이 액세스 토큰은 Python 응용 프로그램에서 응용 프로그램의 보호된 리소스에 대한 액세스 권한을 사용자에게 부여하는 데 사용할 수 있습니다. 3단계 플로우는 권한 부여 코드 권한 부여 유형을 사용합니다.

보안을 강화하기 위해 Oracle은 3단계 플로우를 사용하여 인증을 위해 Python 웹 애플리케이션을 Oracle Identity Cloud Service와 통합할 것을 권장합니다. 권한 부여 코드 유형을 사용하여 다시 인증하지 않고도 Oracle Identity Cloud Service로 보호되는 다른 애플리케이션에 액세스할 수도 있습니다.

Python 응용 프로그램에서 SDK를 사용하기 위한 기본 사용 사례에 대해 알아보기

Python 웹 응용 프로그램은 두 가지 사용 사례를 구현합니다. 하나는 사용자 인증용이고 다른 하나는 로그인한 사용자에 대한 자세한 정보에 액세스하기 위한 것입니다.

다음 데이터 플로우 다이어그램은 각 사용 사례에 대한 웹 브라우저, 웹 애플리케이션 및 Oracle Identity Cloud Service 간의 이벤트, 호출 및 응답 플로우를 보여 줍니다.

그림 - 사용 사례 1: 사용자 인증

다음은 그림 -에 대한 설명입니다.
"그림 - 사용 사례 1: 사용자 인증"에 대한 설명

데이터 흐름은 다음과 같이 발생합니다.

  1. 사용자가 보호된 리소스를 요청합니다.

  2. 인증 모듈은 SDK를 사용하여 Oracle Identity Cloud Service에 대한 요청 권한 부여 코드 URL을 생성하고 이 URL을 웹 브라우저에 재지정 응답으로 전송합니다.

  3. 웹 브라우저가 URL을 호출합니다.

  4. Oracle Identity Cloud Service 사인인 페이지가 나타납니다.

  5. 사용자가 Oracle Identity Cloud Service 사인인 인증서를 제출합니다.

  6. 사용자가 성공적으로 로그인한 후 Oracle Identity Cloud Service는 사용자에 대한 세션을 생성하고 권한 부여 코드를 발행합니다.

  7. 웹 응용 프로그램은 사용자 액세스 토큰에 대한 권한 부여 코드를 교환하기 위해 백엔드(또는 서버 간) 호출을 수행합니다.

  8. Oracle Identity Cloud Service가 액세스 토큰 및 ID 토큰을 발행합니다.

  9. 세션이 설정되고 유저가 Home 페이지로 재지정됩니다.

  10. 웹 애플리케이션의 홈 페이지가 나타납니다.

그림 - 사용 사례 2: 사용자 세부정보 가져오기

다음은 그림 -에 대한 설명입니다.
"그림 - 사용 사례 2: 사용자 세부정보 가져오기"에 대한 설명

데이터 흐름은 다음과 같이 발생합니다.

  1. 사용자가 /myProfile 리소스를 요청합니다.

  2. 웹 애플리케이션은 Oracle Identity Cloud Service의 SDK를 사용하여 ID 토큰을 검증합니다.

  3. ID 토큰 검증에서 반환되는 데이터는 JSON 객체 형식의 사용자 세부정보를 포함합니다.

  4. 내 프로파일 페이지는 JSON 객체를 HTML 콘텐츠로 렌더링합니다.

Python SDK의 방법 및 기능에 대해 알아보기

Python SDK는 웹 애플리케이션에 포함해야 하는 두 개의 python 파일인 IdcsClient.pyConstants.py로 제공됩니다.

이러한 python 파일은 응용 프로그램에도 포함되어야 하는 타사 라이브러리에 종속됩니다. 이 파일을 포함하려면 SDK zip 파일을 열고 README.txtrequirements.txt 파일을 임시 폴더로 추출한 다음 pip install -r requirements.txt 명령을 실행합니다.

샘플 웹 애플리케이션은 함수 형태로 URL 경로를 구현하는 Python DJango 프레임워크를 사용하여 개발되었습니다.

Python SDK에는 Oracle Identity Cloud Service 연결 정보와 함께 로드되는 JSON 변수가 필요합니다. Python 웹 응용 프로그램은 다음 정보를 제공하는 config.json 파일을 사용합니다.

{
   "ClientId" : "123456789abcdefghij",
   "ClientSecret" : "abcde-12345-zyxvu-98765-qwerty",
   "BaseUrl" : "https://idcs-abcd1234.identity.oraclecloud.com",
   "AudienceServiceUrl" : "https://idcs-abcd1234.identity.oraclecloud.com",  
   "scope" : "urn:opc:idm:t.user.me openid",
   "TokenIssuer" : "https://identity.oraclecloud.com/",
   "redirectURL": "http://localhost:8000/callback",
   "logoutSufix":"/oauth2/v1/userlogout",
   "LogLevel":"INFO",
   "ConsoleLog":"True" 
}

다음은 이 SDK의 각 필수 속성에 대한 간략한 설명입니다.

표 - Python SDK에 필요한 속성

속성 이름 속성 설명
ClientId Oracle Identity Cloud Service 콘솔을 사용하여 웹 애플리케이션을 등록한 후 생성되는 클라이언트 ID 값입니다.
ClientSecret Oracle Identity Cloud Service 콘솔을 사용하여 웹 애플리케이션을 등록한 후 생성되는 클라이언트 암호 값입니다.
BaseUrl Oracle Identity Cloud Service 인스턴스의 도메인 URL입니다.
AdminServiceUrl Oracle Identity Cloud Service 인스턴스의 도메인 이름 URL입니다. 일반적으로 BaseUrl와 동일합니다.
TokenIssuer 여기에 제시된 값을 유지하십시오.
scope 범위는 응용 프로그램이 사용자를 대신하여 액세스하거나 처리할 수 있는 데이터를 제어합니다. 응용 프로그램은 인증에 SDK를 사용하기 때문에 범위는 openid입니다. 또한 응용 프로그램은 urn:opc:idm:t.user.me 범위도 사용해야 하는 get user details 사용 사례를 구현합니다.
ConsoleLog SDK 로그를 사용으로 설정합니다.
LogLevel SDK의 로그 레벨을 나타냅니다.

logoutSufixredirectURL 속성은 모두 응용 프로그램에서 사용됩니다. 따라서 SDK에 필요하지 않습니다.

응용 프로그램은 /auth URL을 매핑하는 auth 함수 정의를 구현합니다. 사용자가 Oracle Identity Cloud Service를 사용하여 인증하면 브라우저에서 이 URL을 요청합니다.

auth 함수는 Authentication Manager를 초기화하고, JSON 구성 속성을 매개변수로 사용하고, SDK를 사용하여 Oracle Identity Cloud Service 권한 부여 코드 URL을 생성한 다음, 브라우저를 이 URL로 재지정합니다.

#Loading the SDK Python file.
from . import IdcsClient
 
#Function used to load the configurations from the config.json file
def getOptions():
    fo = open("config.json", "r")
    config = fo.read()
    options = json.loads(config)
    return options
 
# Definition of the /auth route
def auth(request):
    #Loading the configurations
    options = getOptions()
    print "config.json file = %s" % options
    #Authentication Manager loaded with the configurations.   
    am = IdcsClient.AuthenticationManager(options)
    #Using Authentication Manager to generate the Authorization Code URL, passing the 
    #application's callback URL as parameter, along with code value and code parameter.    
    url = am.getAuthorizationCodeUrl(options["redirectURL"], options["scope"], "1234", "code")
    #Redirecting the browser to the Oracle Identity Cloud Service Authorization URL.
    return HttpResponseRedirect(url)

인증 코드 URL을 생성하는 데 사용되는 매개변수는 다음과 같습니다.

표 - 인증 코드 URL을 생성하는 데 사용되는 매개변수

매개변수 이름 매개변수 설명
options["redirectURL"] 성공적으로 사인인한 후 Oracle Identity Cloud Service는 사용자의 웹 브라우저를 이 URL로 재지정합니다. 이 URL은 Oracle Identity Cloud Service 콘솔에서 신뢰할 수 있는 애플리케이션에 대해 구성할 URL과 일치해야 합니다.
options["scope"] 인증의 OAuth 또는 OpenID Connect 범위입니다. 이 애플리케이션에는 openid 인증만 필요합니다.
state 웹 애플리케이션은 이 코드를 사용하여 Oracle Identity Cloud Service에 대한 통신을 설정할 수 있는지 여부를 확인합니다. 이 매개변수는 OAuth 프로토콜로 정의됩니다.
response_type 권한 부여 코드 권한 부여 유형에 필요한 값(예: code)입니다.

callback 함수는 권한 부여 코드 URL 매개변수를 사용하여 액세스 토큰 및 ID 토큰을 요청합니다. 두 토큰은 나중에 사용할 수 있도록 사용자 세션에 저장됩니다.

# Definition of the /callback route
def callback(request):
   code = request.GET.get('code')
   #Authentication Manager loaded with the configurations.
   am = IdcsClient.AuthenticationManager(getOptions())
   #Using the Authentication Manager to exchange the Authorization Code to an Access Token.
   ar = am.authorizationCode(code)
   #Get the access token as a variable    
   access_token = ar.getAccessToken()    
   id_token = ar.getIdToken()

   #Validating id token to acquire information such as UserID, DisplayName, list of groups 
   #and AppRoles assigned to the user    
   id_token_verified = am.verifyIdToken(id_token)

   displayname = id_token_verified.getDisplayName()
   #The application then adds these information to the User Session.
   request.session['access_token'] = access_token
   request.session['id_token'] = id_token
   request.session['displayname'] = displayname
   #Rendering the home page and adding displayname to be printed in the page.
   return render(request,'sampleapp/home.html', {'displayname': displayname})

myProfile 함수는 사용자의 ID 토큰에 액세스하고, AuthenticationManager verifyIdToken 함수를 호출하여 사용자에게 지정된 이름, 그룹 및 애플리케이션과 같은 사용자 정보를 JSON 텍스트로 검색한 다음 렌더링을 위해 정보를 myProfile.html로 전송합니다.

# Definition of the /myProfile route
def myProfile(request):
   #Getting the Access Token value from the session
   access_token = request.session.get('access_token', 'none')
   if access_token == 'none':
       #If the access token isn't present redirects to login page.
       return render(request, 'sampleapp/login.html')
   else:
       #If the access token is present, validates the id token to acquire
       #information such as UserID, DisplayName, list of groups and AppRoles assigned to the user.

       #Authentication Manager loaded with the configurations.
       am = IdcsClient.AuthenticationManager(getOptions())        
       id_token = request.session.get('id_token', 'none')
       id_token_verified = am.verifyIdToken(id_token)

       #Getting the user details in json format.        
       jsonProfile = id_token_verified.getIdToken()
       #Getting User information to send to the My Profile page.        
       displayname = request.session.get('displayname', 'displayname')

       #Redenring json to be used in the html page.
       json_pretty = json.dumps(jsonProfile, sort_keys=True, indent=2)        
       context = {
          'displayname': displayname,
          "json_pretty": json_pretty,
       }
       #Rendering the content of the My Profile Page.
       return render(request, 'sampleapp/myProfile.html', context)

애플리케이션과 Oracle Identity Cloud Service 간의 단일 사인온에서 사용자를 사인아웃하려면 Python 웹 애플리케이션이 logout 함수를 구현합니다. 이 함수는 이전에 설정된 사용자 세션 속성을 지운 다음 사용자를 Oracle Identity Cloud Service의 OAuth 로그아웃 URL로 재지정합니다. 이 URL은 config.json 파일에서 logoutSufix 매개변수로 설정됩니다.

# Definition of the /logout route
def logout(request):
   #Getting the Access Token value from the session
   access_token = request.session.get('access_token', 'none')
   if access_token == 'none':
        #If the access token isn't present redirects to login page.
        return render(request, 'sampleapp/login.html') 
   else:
       options = getOptions()        
       url = options["BaseUrl"]        
       url += options["logoutSufix"]        
       url += '?post_logout_redirect_uri=http%3A//localhost%3A8000&id_token_hint='        
       url += request.session.get('id_token', 'none')
       #Clear session attributes
       del request.session['access_token']
       del request.session['id_token']
       del request.session['displayname']
       #Redirect to Oracle Identity Cloud Service logout URL.
       return HttpResponseRedirect(url)