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의 메소드 및 기능

위협 인증 플로우에 대해 알아보기

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

보안 강화를 위해 Oracle 인증 시 Python 웹 애플리케이션을 Oracle Identity Cloud Service 에 통합하는 데 3가지 플로우를 사용하는 것이 좋습니다. 권한 부여 코드 권한 부여 유형을 사용하면 재인증 없이 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 액세스 토큰을 발행합니다.

  9. 세션이 설정되고 사용자가 홈 페이지로 재지정됩니다.

  10. 웹 응용 프로그램의 홈 페이지가 나타납니다.

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

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

데이터 플로우는 다음과 같은 방식으로 발생합니다.

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

  2. 웹 애플리케이션은 SDK를 사용하여 Oracle Identity Cloud Service 을 호출합니다. 그러면 사용자 세션에 매개변수로 저장된 액세스 토큰이 사용됩니다.

  3. 사용자 세부정보가 JSON 객체로 웹 애플리케이션으로 전송됩니다.

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

Python SDK의 메소드 및 기능에 대해 알아보기

Python SDK는 웹 애플리케이션에 포함해야 하는 두 개의 python 파일(IdcsClient.pyConstants.py) 로 사용할 수 있습니다. 이러한 python 파일은 애플리케이션에 포함되어야 하는 타사 라이브러리에도 종속됩니다. 이러한 명령을 포함하려면 다음 pip install 명령을 실행합니다.

pip install simplejson==3.13.2
pip install cryptography==2.1.4
pip install PyJWT==1.5.2
pip install requests==2.18.4
pip install six==1.10.0
pip install py3_lru_cache==0.1.6

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

Python SDK에는 Oracle Identity Cloud Service 접속 정보로 로드된 JSON 변수가 필요합니다. Python 웹 애플리케이션은 다음 정보를 제공하는 config.json 파일을 사용합니다.

//Oracle Identity Cloud Service connection parameters as a json var
{
   "ClientId" : "clientid",
   "ClientSecret" : "clientsecret",
   "BaseUrl" : "https://idcs-1234.identity.oraclecloud.com",
   "AudienceServiceUrl" : "https://idcs-1234.identity.oraclecloud.com",
   "TokenIssuer" : "https://identity.oraclecloud.com",
   "scope" : "urn:opc:idm:t.user.me openid",
   "redirectURL": "http://localhost:8000/callback",
   "logoutSufix":"/oauth2/v1/userlogout"
}

다음은 이 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 사용 사례를 구현합니다.

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()
    #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 접속 범위입니다. 이 애플리케이션에는 openid 인증만 필요합니다.
state 웹 애플리케이션은 이 코드를 사용하여 Oracle Identity Cloud Service 통신을 설정할 수 있는지 확인합니다. 매개변수는 OAuth 프로토콜로 정의됩니다.
response_type 권한 부여 코드 권한 부여 유형(예: code) 에 필요한 값입니다.

callback 함수는 권한 부여 코드 URL 매개변수를 사용하여 액세스 토큰을 요청합니다. 액세스 토큰은 쿠키로 저장되며 이후 사용을 위해 브라우저에 전송됩니다.

# 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()
   #User Manager loaded with the configurations.
   um = IdcsClient.UserManager(getOptions())
   #Using the access_token value to get an object instance representing the User Profile.
   u = um.getAuthenticatedUser(access_token)
   #Getting the user details in json object format.
   displayname = u.getDisplayName()
   #The application then adds these information to the User Session.
   request.session['access_token'] = access_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 함수는 사용자의 액세스 토큰에 액세스하고, getAuthenticatedUser 함수를 호출하여 사용자 정보를 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, then loads the User Manager with the configurations.
       am = IdcsClient.UserManager(getOptions())
       #Using the access_token value to get an object instance representing the User Profile.
       u = am.getAuthenticatedUser(access_token)
       #Getting the user details in json format.
       jsonProfile = json.dumps(u.getUser())
       #Getting User information to send to the My Profile page.
       displayname = request.session.get('displayname', 'displayname')
       #Rendering the content of the My Profile Page.
       return render(request, 'sampleapp/myProfile.html', {'displayname': displayname, 'jsonProfile':jsonProfile})

애플리케이션과 Oracle Identity Cloud Service 간에 Single Sign-On에서 사용자를 사인아웃하려면 Python 웹 애플리케이션이 logout 함수를 구현합니다. 이 함수는 사용자 세션을 무효화한 다음 사용자를 Oracle Identity Cloud Service OAuth 로그아웃 URL로 재지정합니다. 이 URL은 config.json 파일에서 logoutSufix 매개변수로 설정됩니다.

# Definition of the /logout route
def logout(request):
    options = getOptions()
    url = options["BaseUrl"]
    url += options["logoutSufix"]
    del request.session['access_token']
    del request.session['displayname']
    return HttpResponseRedirect(url)