了解OAuth2和OpenID Connect

2020-09-07 09:00:39

缺少任何选项都将导致以下异常:17:10:55,400 Error[org.jboss.as.controller.management-operation](控制器引导线程)WFLYCTL0013:操作(";添加";)失败-地址:([(";子系统";=>;&34;微配置文件指标-Smallrye";)]):java.lang.NullPointerException。

用户可以使用以下docker合成文件,而不是分别执行这两个docker命令:

Postgres-keycloak.yml版本:';3';网络:默认:外部:名称:my-iam-netservices:postgres:容器名称:postgres image:postgres:12.4卷:-${HOME}/Downloads/DATA/postgres:/var/lib/postgresql/data环境:-postgres_DB=KEYWOAK-Postgres_USER=KEYCLOAK-POSTGRES_PASSWORD=${Postgres_PASSWORD}端口:-5432:5432KEATWAK:CONTAINER_NAME:KEYWARK WAKAK映像:JBOSS/KEYWOAK:11.0.1环境:-DB_VADVER=POSTGRES-DB_DATABASE。DB_USER=KEYCLOAK-DB_PASSWORD=${Postgres_Password}-KEYCLOAK_USER=ADMIN-KEYCLOAK_PASSWORD=${KEYCLOAK_PASSWORD}端口:-8080:8080依赖于:-Postgres。

启动Web浏览器并打开URL http://localhost:8080/auth/admin.。它将提示我们登录屏幕,如下图所示:

输入用户名admin,密码kc_admin$123,点击登录按钮,如下图所示:

成功登录后,我们将进入主领域页面,如下图所示:

领域类似于所有实例设置对象驻留的名称空间。我们需要为我们的设置创建一个新的领域。要创建新领域,请单击Master下拉菜单(左上角),然后单击Add Realm按钮,如下图所示:

我们将为我们的设置创建一个名为Testing的新域,并单击Create按钮,如下图所示:

成功创建后,它将把我们带到测试领域页面,在此我们输入显示名称,保持其余选项不变,然后单击Save按钮,如下图所示:

在测试领域页面上,单击OpenID Endpoint Configuration,如下图所示:

这将把我们带到Endpoint Configuration(端点配置)页面,在这里我们可以记下各种URL端点,以便稍后进行演示,如下图所示:

与Keyloak交互的每个应用程序都需要预先注册。要创建新客户端,请单击Clients选项(在左侧),然后单击Create按钮,如下图所示:

在Add Client页面上,我们将输入一个名为http://localhost:5000/,-Client的新客户端ID,输入要保存的根URL,然后单击保存按钮,如下图所示:

成功创建后,它将带我们进入Test-Client Client页面,在此我们输入名称、描述、有效的重定向URI,保留其余选项不变,然后单击Save按钮,如下图所示:

在上面的图12中,选项Standard flow enable(包含在一个矩形内)启用了OAuth2流。

我们需要记下与刚刚创建的客户端测试客户端相关联的秘密令牌。为此,请单击Clients选项(在左侧),然后单击客户端列表中的Client ID test-client,如下图所示:

这将把我们带到Test-Client客户端页面。单击Credentials(凭据)选项卡,记下Client Secret(客户端密码),如下图所示:

要让OAuth2流在Keyshaak中工作,我们需要预先注册一个用户(资源所有者)。要创建新用户,请单击Users(用户)选项(在左侧),然后单击Add User(添加用户)按钮(右上角),如下图所示:

成功创建后,它将把我们带到Add User页面,在该页面中,我们输入名为test-user的用户名,电子邮件为test-user@localhost,名为Test,姓为user,其余选项保持不变,然后单击Save按钮,如下图所示:

接下来,我们需要为新创建的用户test-user设置用户凭据(密码)。要设置用户密码,请单击Credentials(凭证)选项卡(圈1),输入test-user$123的密码,重新输入相同的密码以确认,关闭选项Temporary(圈2),然后单击Set Password(设置密码)按钮(圈3),如下图所示:

我们将使用Python实现客户端(作为独立的Web服务器),并在一个简单的HTML页面上显示OAuth2授权代码流的数据元素。

Index.html<;!DOCTYPE html>;<;html lang=";en";>;<;head>;<;!--必需的meta标记-->;<;meta charset=";utf-8";>;<;meta name=";viewport";content=";width=device-width,<;link rel=";href=";../static/css/bootstrap.min.css";>;<;link rel=";快捷图标";href=";../static/images/favicon.ico";>;<;style>;td{空白:正常!重要;换行:Break-Word;}表{table-layout:Fixed;}<;/style>;<;/head>;<;body class=";bg-light";>;<;div class=";CONTAINER";>;br/>;<;div class=";display-4文本中心文本辅助&34;>;理解OAuth2<;/div>;<;br/>;<;<;a id=";CODE";CLASS=";NAV-ITEM NAV-LINK";href=";http://localhost:5000/auth_code";>;Authorization代码<;/a&><;a id=";TOKEN&34;CLASS=";NAV-ITEM NAV-LINK";href=";http://localhost:5000/access_token";>;Access TOKEN<;/a>;<;A id=";配置文件";class=";NAV-Item NAV-LINK";href=";http://localhost:5000/user_profile";>;User配置文件<;/a&><;a id=";注销";NAV-Item NAV-LINK";href=";http://localhost:5000/logout";>;Logout<;/a>;<;/NAV&>。Br/>;<;table class=";表格条纹表-Borded&34;>;<;thead>;<;tr class=";bg-二级文本-light&34;>;<;th width=";20%";>;key<;/th>;<;th width=";80%";/thead>;<;tbody>;<;tr>;<;td>;State<;/td>;<;{{data[';state&39;]}}<;/td>;<;/tr>;<;tr>;<;td>;授权码<;{{data[';code';]}}<;/td>;<;/tr>;<;tr>;<;td>;会话<;/td>;<;{{data[';session&39;]}<;/td>;<;/tr>;<;tr&。Td>;{{data[';a_Token&39;]}}<;/td>;<;/tr>;<;tr>;<;/td>;刷新令牌<;/td>;{{data[';r_Token&39;]}}<;/td>;<;/tr。/td>;<;td>;{{data[';t_type';]}}<;/td>;<;/tr>;<;tr>;<;范围<;/td>;<;td>;{{data[';Scope&39;]}}<;/td>;&。用户电子邮件<;/td&>;<;{{data[';Email&39;]}}<;/td>;<;/tr>;<;/tbody>;<;/TABLE>;<;/div>;<;Script src=";../static/js/jquery.slim.min.js";>;<;/script>;<;src=";../static/js/bootstrap.bundle.min.js";>;<;/script>;<;/Body>;<;/html>;

AuthCode.py#@作者:巴斯卡尔S#@博客:https://www.polarsparc.com#@Date:2020年9月5日#导入随机导入请求端口字符串从烧瓶导入Flask,jsonify,Render_Template,REDIRECT,requestfrom urllib。parse import urlencode app=flask(__NAME__)OAuthConfig={';authURL';:';http://localhost:8080/auth/realms/testing/protocol/openid-connect/auth?';,';tokenURL';:';Http://localhost:8080/auth/realms/testing/protocol/openid-connect/token';,';配置文件URL';:';http://localhost:8080/auth/realms/testing/protocol/openid-connect/userinfo';,';登录URL';:';http://localhost:8080/auth/realms/testing/protocol/openid-connect/logout?';}oauth={';代码';:';';,';状态';:';';,';会话';:';';,';a_Token';:';';,';r_Token';:';';,';t_type';:';';,';作用域';

现在,启动Web浏览器并打开URL http://localhost:5000.。我们将进入一个页面,如下图所示:

单击Item Authorization Code触发Python方法Authenticate()的执行,该方法向Keyloak Authorization Server上的URL端点http://localhost:8080/auth/realms/testing/protocol/openid-connect/auth发送HTTP重定向请求。

在我们的设置中,Keyshaak实例同时充当授权服务器和资源服务器。密钥罩授权服务器收到授权码请求后,会重定向用户(资源所有者)进行身份验证,如下图所示:

输入test-user的用户名和test-user$123的密码,然后单击Log In按钮。

身份验证成功后,Keyloak Authorization Server将使用有效的授权码对Python客户机http://localhost:5000/callback的回调URL进行响应。

浏览器现在会刷新,我们将进入一个页面,如下图所示:

单击项目访问令牌将触发Python方法Token()的执行,该令牌将向Keyloak Authorization Server上的URL端点http://localhost:8080/auth/realms/testing/protocol/openid-connect/token发送HTTP post请求(带有授权码和客户端密码)。

如果成功,Keyloak授权服务器会向Python客户端返回一个访问令牌。

浏览器现在会刷新,我们将进入一个页面,如下图所示:

单击项目用户配置文件将触发Python方法profile()的执行,该配置文件将向Keyloak Resource Server上的URL端点http://localhost:8080/auth/realms/testing/protocol/openid-connect/userinfo发送一个HTTP请求(在HTTP Authorization报头中将访问令牌作为承载令牌)。

如果成功,Keyloak资源服务器会向Python客户端返回用户(资源所有者)的配置文件信息,其中包括他们的电子邮件ID。

浏览器现在会刷新,我们将进入一个页面,如下图所示:

单击项Logout将触发Python方法logout()的执行,该方法向Keyloak Authorization Server上的URL端点http://localhost:8080/auth/realms/testing/protocol/openid-connect/logout发送HTTP请求,以注销并终止活动的用户会话,并使访问令牌无效。

隐式授予流是OAuth2流的简化版本,其安全性较低,主要针对基于单页JavaScript的应用程序,无需先获取授权码,然后交换访问令牌,即可直接获取访问令牌。所有交互仅通过前通道进行。隐式授予流的工作方式如下:

2::客户端从前端通道向授权服务器请求访问令牌(跳过授权码步骤),在客户端传入REQUEST_TYPE=令牌和要响应(/回调)的URL。

3::授权服务器将资源所有者重定向到资源服务器,以进行用户身份验证和访问授权

4::资源所有者输入由资源服务器验证的有效凭据,然后重定向回授权服务器。

5::授权服务器直接生成访问令牌,在指定的URL(/callback)中将访问令牌作为*分片ID*返回给客户端。

6::客户端使用访问令牌请求访问资源服务器上的资源。

资源所有者密码流的目标是用户(资源所有者)信任客户端直接获取访问令牌,以换取资源所有者的用户名/密码,而无需先获取授权码,然后交换访问令牌。所有的交互都只通过反向通道进行。资源所有者密码流的工作方式如下:

2::客户端通过反向通道向授权服务器请求访问令牌(跳过授权码步骤),传入GRANT_TYPE=PASSWORD、客户端ID和密码以及资源所有者的用户名和密码。

3::授权服务器验证资源所有者凭据,成功时生成访问令牌并响应客户端(使用访问令牌)。

4::客户端使用访问令牌请求访问资源服务器上的资源。

如果正在运行,则停止Python客户端AuthCode.py,并启动Python客户端OwnerPass.py以查看此流的运行情况。

下图显示了查看项目访问令牌和用户配置文件后的浏览器页面:

客户端凭据流面向这样的用例:客户端既是服务又是资源所有者,并且希望获得访问令牌来访问其自己的资源。所有的交互都只通过反向通道进行。客户端凭据流的工作方式如下:

1::客户端通过反向通道向授权服务器请求访问令牌(跳过授权码步骤),将GRANT_TYPE=CLIENT_Credentials与客户端ID(服务帐户)和密码一起传递。

2::授权服务器验证服务帐户,成功时生成访问令牌并响应客户端(使用访问令牌)。

3::客户端使用访问令牌请求访问资源服务器上的资源。

在我们继续之前,我们需要在Test-Client客户端页面中做一个小更改。我们需要启用选项Service Accounts Enabled,然后单击保存按钮,如下图所示:

停止Python客户端AuthCode.py或OwnerPass.py(如果正在运行),并启动Python客户端ClientCredential.py以查看此流程的运行情况。

下图显示了查看项目访问令牌和用户配置文件后的浏览器页面:

本文中的代码是为了理解OAuth2和OIDC流-它纯粹是为了学习目的。