了解 Python 应用与 Oracle Identity Cloud Service 之间的验证

您已准备好了解 Python Web 应用程序与 Oracle Identity Cloud Service 之间的验证。这包括了解以下内容:

  • 将 SDK 与 Python 应用结合使用以通过 Oracle Identity Cloud Service 进行验证的用例。

  • Oracle Identity Cloud Service 为 Python SDK 支持的三路验证流

  • Python SDK 的方法和函数

了解三路验证流

Oracle Identity Cloud Service 支持 Python SDK 的三路验证流。在此流中,用户直接与 Oracle Identity Cloud Service 交互。用户登录后,Oracle Identity Cloud Service 会发出 SDK 为用户访问令牌交换的授权代码。Python 应用程序可以使用此访问令牌向用户授予对应用程序中受保护资源的访问权限。三路流使用授权代码授权类型。

为了提高安全性,Oracle 建议您使用三路流将 Python Web 应用程序与 Oracle Identity Cloud Service 集成以进行验证。通过使用授权代码授权类型,您还可以访问受 Oracle Identity Cloud Service 保护的其他应用程序,而无需重新验证。

了解将 SDK 与 Python 应用程序结合使用的主要用例

Python Web 应用程序实现两个用例:一个用于验证用户,另一个用于访问有关已登录用户的详细信息。

以下数据流图说明了 Web 浏览器、Web 应用程序和 Oracle Identity Cloud Service 之间每个用例的事件、调用和响应的流。

图 - 用例 1:用户验证

后面是图 - 的说明
“图 - 用例 1:用户验证”的说明

数据流以以下方式进行:

  1. 用户请求受保护的资源。

  2. 验证模块使用 SDK 为 Oracle Identity Cloud Service 生成请求授权代码 URL,并将此 URL 作为重定向响应发送到 Web 浏览器。

  3. Web 浏览器调用 URL。

  4. 此时将显示 Oracle Identity Cloud Service 登录页。

  5. 用户提交其 Oracle Identity Cloud Service 登录身份证明。

  6. 用户成功登录后,Oracle Identity Cloud Service 将为用户创建会话并发出授权代码。

  7. Web 应用程序进行后端(或服务器到服务器)调用以交换用户访问令牌的授权代码。

  8. Oracle Identity Cloud Service 发出访问令牌和 ID 令牌。

  9. 将建立会话,并将用户重定向到主页。

  10. 此时将显示 Web 应用程序的主页。

图 - 用例 2:获取用户详细信息

后面是图 - 的说明
“图 - 用例 2:获取用户详细信息”的说明

数据流以以下方式进行:

  1. 用户请求 /myProfile 资源。

  2. Web 应用程序使用 Oracle Identity Cloud Service 的 SDK 验证 ID 令牌。

  3. 从 ID 标记验证返回的数据包含 JSON 对象格式的用户详细信息。

  4. 我的概要信息页将 JSON 对象呈现为 HTML 内容。

了解 Python SDK 的方法和函数

Python SDK 提供两个 python 文件,即 IdcsClient.pyConstants.py,您必须将其包含在 Web 应用程序中。

这些 python 文件依赖于第三方库,这些库也必须包含在您的应用程序中。要包括这些文件,请打开 SDK zip 文件,将 README.txtrequirements.txt 文件提取到临时文件夹,然后运行 pip install -r requirements.txt 命令。

使用 Python DJango 框架开发了一个示例 Web 应用程序,该框架以函数形式实现 URL 路由。

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 的日志级别。

应用程序都使用 logoutSufixredirectURL 属性。因此,SDK 不需要它们。

应用程序实施 auth 函数定义,该定义映射 /auth URL。当用户使用 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)