PythonアプリケーションとOracle Identity Cloud Service間の認証について学習
Python WebアプリケーションとOracle Identity Cloud Service間の認証について学習する準備ができました。これには、次の内容の理解が含まれます。
-
PythonアプリケーションでSDKを使用してOracle Identity Cloud Serviceで認証する場合のユース・ケース。
-
Oracle Identity Cloud ServiceがPython SDKに対してサポートする3-legged認証フロー
-
Python SDKのメソッドおよび関数
3-Legged認証フローについて学習
Oracle Identity Cloud Serviceでは、Python SDKの3-legged認証フローがサポートされています。このフローでは、ユーザーはOracle Identity Cloud Serviceと直接対話します。ユーザーがサインインすると、Oracle Identity Cloud Serviceは、SDKがユーザー・アクセス・トークンと交換する認可コードを発行します。このアクセス・トークンは、Pythonアプリケーションによって、アプリケーション内の保護されたリソースへのアクセス権をユーザーに付与するために使用できます。3-leggedフローでは、認可コード付与タイプが使用されます。
セキュリティを強化するために、Oracleでは、認証のためにPython WebアプリケーションをOracle Identity Cloud Serviceと統合するために、3-leggedフローを使用することをお薦めします。認可コード付与タイプを使用すると、再認証しなくても、Oracle Identity Cloud Serviceによって保護されている他のアプリケーションにアクセスすることもできます。
PythonアプリケーションでSDKを使用するための主なユースケースについて学習
Python Webアプリケーションは、2つのユースケースを実装します。1つはユーザーの認証用、もう1つはログインしているユーザーに関する詳細情報へのアクセス用です。
次のデータ・フロー図は、各ユース・ケースのWebブラウザ、WebアプリケーションおよびOracle Identity Cloud Service間のイベント、コールおよびレスポンスのフローを示しています。
データ・フローは次のようになります。
-
ユーザーが保護されたリソースをリクエストします。
-
認証モジュールは、SDKを使用してOracle Identity Cloud Serviceのrequest-authorization-code URLを生成し、このURLをWebブラウザへのリダイレクト・レスポンスとして送信します。
-
WebブラウザがURLをコールします。
-
Oracle Identity Cloud Serviceのサインイン・ページが表示されます。
-
ユーザーがOracle Identity Cloud Serviceのサインイン資格証明を送信します。
-
ユーザーが正常にログインすると、Oracle Identity Cloud Serviceはユーザーのセッションを作成し、認可コードを発行します。
-
Webアプリケーションは、ユーザー・アクセス・トークンの認可コードを交換するためのバックエンド(またはサーバー間)呼出しを行います。
-
Oracle Identity Cloud Serviceは、アクセス・トークンとIDトークンを発行します。
-
セッションが確立され、ユーザーはホーム・ページにリダイレクトされます。
-
Webアプリケーションのホームページが表示されます。
データ・フローは次のようになります。
-
ユーザーは
/myProfile
リソースをリクエストします。 -
Webアプリケーションは、Oracle Identity Cloud ServiceのSDKを使用してIDトークンを検証します。
-
IDトークン検証から返されるデータには、JSONオブジェクトの形式でユーザーの詳細が含まれます。
-
「マイ・プロファイル」ページでは、JSONオブジェクトがHTMLコンテンツとしてレンダリングされます。
Python SDKのメソッドおよび関数について学習
Python SDKは、Webアプリケーションに含める必要がある2つのpythonファイルIdcsClient.py
およびConstants.py
として使用できます。
これらのpythonファイルは、アプリケーションにも含める必要があるサード・パーティ・ライブラリに依存します。これらを含めるには、SDK zipファイルを開き、README.txt
ファイルとrequirements.txt
ファイルの両方を一時フォルダに抽出して、pip install -r requirements.txt
コマンドを実行します。
サンプルWebアプリケーションは、関数の形式でURLルートを実装するPython DJangoフレームワークを使用して開発されました。
Python SDKには、Oracle Identity Cloud Service接続情報とともにロードされるJSON変数が必要です。Python Webアプリケーションは、次の情報を提供する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コンソールを使用してWebアプリケーションを登録した後に生成されるクライアントIDの値。 |
ClientSecret |
Oracle Identity Cloud Serviceコンソールを使用してWebアプリケーションを登録した後に生成されるクライアント・シークレットの値。 |
BaseUrl |
Oracle Identity Cloud ServiceインスタンスのドメインURL。 |
AdminServiceUrl |
Oracle Identity Cloud Serviceインスタンスのドメイン名URL。通常はBaseUrl と同じです。
|
TokenIssuer |
ここに示した値を保持します。 |
scope |
スコープによって、ユーザーがアクセスまたは処理できるデータが制御されます。アプリケーションは認証にSDKを使用するため、スコープはopenid です。アプリケーションはget user details ユースケースも実装します。このユースケースでは、スコープurn:opc:idm:t.user.me も使用する必要があります。
|
ConsoleLog |
SDKログを有効にします。 |
LogLevel |
SDKのログ・レベルを示します。 |
logoutSufix
属性とredirectURL
属性はどちらもアプリケーションで使用されます。そのため、SDKでは必要ありません。
アプリケーションは、/auth
URLをマップするauth
関数定義を実装します。ユーザーがOracle Identity Cloud Serviceで認証されると、ブラウザはこのURLに対してリクエストを行います。
auth
関数は、認証マネージャを初期化し、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はユーザーのWebブラウザをこのURLにリダイレクトします。このURLは、Oracle Identity Cloud Serviceコンソールで信頼できるアプリケーション用に構成するURLと一致する必要があります。 |
options["scope"] |
認証のOAuthまたはOpenID Connectスコープ。このアプリケーションでは、openid 認証のみが必要です。
|
state |
Webアプリケーションは、このコードを使用して、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 Webアプリケーションは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)