使用OAuth2进行身份验证¶
本教程介绍GeoServer OAuth2支持,并介绍针对OAuth2提供程序设置身份验证的过程。建议 身份验证链 在继续之前请阅读。
OAuth2协议和地理服务器OAuth2核心模块¶
此模块允许GeoServer根据 OAuth2 Protocol .
为了使模块正常工作,必须同时设置和配置 oauth2 和 oauth2-xxxx-extension (其中xxxx是提供商,例如Google、GitHub、OpenID、geonode)。这两个文件都包含在一个ZIP文件中,该文件从 GeoServer build server (根据需要更改版本)-搜索 sec-oauth2 。
第一个包含OAuth2核心模块的必要依赖项。此模块包含地理服务器安全筛选器、OAuth2令牌服务的基类和地理服务器GUI面板的实现。
第二个为每个提供者提供OAuth2实现。由于在几乎所有情况下,OAuth2提供程序之间唯一不同的是端点URI和客户端连接信息(不仅是密钥-公共和秘密-还有用户配置文件表示),为了允许Geoserver连接到特定的OAuth2提供程序,只需安装OAuth2核心模块插件(并通过Geoserver图形用户界面正确配置参数-有关详细信息,请参阅下一节)以及OAuth2 REST令牌模板和资源详细信息的具体实现。
目前,这个模块附带了Google OAuth2 Provider的示例扩展。这是一个特殊的情况,因为Google JWT的响应不是标准的,因此我们必须定义并注入 GoogleUserAuthenticationConverter 对一个有效的 access_token 并将其转换为OAuth2标准版本。
除此之外,最有趣的部分是基类的实现 GeoServerOAuth2SecurityConfiguration .
后者包含 OAuth2RestTemplate .
在下一节中,我们将看到如何在对GoogleOAuth2提供者进行身份验证的geoserver上安装和配置OAuth2安全过滤器。
配置Google身份验证提供程序¶
首先要做的是配置OAuth2提供程序并获取 Client ID 和 Client Secret 钥匙。
从Google API控制台获取OAuth 2.0凭证。
参观 Google API Console 以获取OAuth 2.0凭据,如Google和应用程序都知道的客户端ID和客户端机密。值集根据您正在构建的应用程序类型而变化。例如,JavaScript应用程序不需要机密,但web服务器应用程序需要。
使用有效的Google帐户登录
点击
APIs & Services
点击
Credentials
备注
第一次登陆时,谷歌会要求至少创建一个项目。
在本教程中,我们将创建一个示例项目。您可以通过 Google API Console 后来。
如果没有
Credentials如果存在,将要求您创建新的。
选择现有的(或创建新的)
OAuth Client ID
配置新的
Web application如果这是您第一次创建
OAuth Client ID,将要求您创建新的consent screen
自定义
consent screen警告
仅当您是第一次定义
Web application在一个新项目上。如果您没有组织,则只能从下面的屏幕中选择外部类型。
- 填写下面的表格并点击
save and continue直到所有标签都填满为止。
备注
稍后也可以对其进行编辑和更新(请参阅下面这一节的最后一点)
- 填写下面的表格并点击
在凭据页面中,单击
CREATE CREDENTIALS>OAuth Client ID并选择Application type->Web application警告
只有在第一次定义
Web application在一个新项目上。
添加
Name以及Authorized redirect URIs如下所示。备注
此示例创建一个处理默认本地URL的客户端
http://localhost:8080/geoserver. 当然,这只适用于本地实例,不能用于生产系统。但是,可以添加尽可能多的
Authorized redirect URIs你需要一个新的Web application.也可以创造许多
Client credentials定制的consent screen和Web application,这取决于您的具体需要。每个公共GeoServer实例(或属于特定项目的GeoServer集群)都应该有自己的特定Client credentials.
备注
始终为每个URI添加两个条目。一个没有结尾的
/还有一个。
点击
Create并注意到Client ID以及Client Secret.在程序结束时,Google将显示一个小对话框,其中
Client ID以及Client Secret. 这些信息总是可以从 Google API Console
(可选)自定义
OAuth consent screen.可以随时更新和自定义
OAuth consent screen.你可以把你的标志,应用名称,TOS等等放在这里。
配置geoserver oauth2筛选器¶
启动geoserver并以
admin用户。单击
Authentication链接位于Security导航边栏的部分。
向下滚动到
Authentication Filters面板并单击Add new链接。
单击
OAuth2链接。
按如下方式填写设置表单的字段:
插件提供的默认值对Google OAuth2提供程序有效,如下所示:
"Enable Redirect Authentication EntryPoint" = False "Access Token URI" = https://accounts.google.com/o/oauth2/token "User Authorization URI" = https://accounts.google.com/o/oauth2/auth "Redirect URI" = http://localhost:8080/geoserver "Check Token Endpoint URL" = https://www.googleapis.com/oauth2/v1/tokeninfo "Logout URI" = https://accounts.google.com/logout "Scopes" = https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/userinfo.profile
备注
Client ID和Client Secret是谷歌提供的吗选择一个
Role Service能够将用户电子邮件识别为ID。默认情况下,连接的用户将ROLE_USER角色
警告
几句话 启用重定向身份验证入口点 选项
此选项允许您决定是否 力 是否自动重定向到OAuth2访问令牌URI进行身份验证。
那是什么意思?
启用重定向身份验证入口点 =真
如果尚未验证(或没有有效的 访问令牌 在查询字符串中提供),此选项将 力 重定向到OAuth2提供程序登录页。
这可能会导致不需要的行为,因为它将重写其他所有显式登录方法,如
form. 换句话说,如果过滤器应用于web端点,将无法通过浏览器使用标准登录方法访问GeoServer管理GUI。启用重定向身份验证入口点 =假
为了避免上述问题,通过禁用此选项,您将 强迫 使用显式身份验证终结点通过OAuth2提供程序登录页登录。
如果尚未验证(或没有有效的 访问令牌 在查询字符串中提供) must 通过以下URL进行身份验证:
GeoServer OAuth2授权终结点 ;
http://<host:port>/geoserver/j_spring_oauth2_loginOAuth2提供程序显式用户授权终结点 ;这必须适合您的特定OAuth2提供者,协议规定它应该
https://<USER_AUTHORIZATION_URI>?scope=<SCOPES>&response_type=code&redirect_uri=<REDIRECT_URI>&client_id=<CLIENT_ID>
对于Google OAuth2,提供程序是:
https://accounts.google.com/o/oauth2/auth?scope%3Dhttps://www.googleapis.com/auth/userinfo.email%2Bhttps://www.googleapis.com/auth/userinfo.profile%26response_type%3Dcode%26redirect_uri%3D<REDIRECT_URI>%26client_id%3D<CLIENT_ID>
通过添加新的OAuth2筛选器来更新筛选器链。
配置完所有内容后,您应该能够看到新的
oauth2过滤器可用于Authentication Filters列表
通过这一点,始终可以修改/更新过滤器选项,或创建更多选项。
下一步是将过滤器添加到
Filter Chains你还想用OAuth2来保护
为要使用OAuth2保护的每个筛选器链选择OAuth2筛选器。
如果你需要保护 all GeoServer服务和GeoServer管理GUI对于OAuth2,还需要添加
oauth2过滤到以下所有链webrestgwcdefault
身份验证筛选器的顺序基本上取决于您希望GeoServer使用哪种方法 先试试看 .
备注
在身份验证过程中
Filter Chain连续执行,直到一个成功为止(有关详细信息,请参阅 身份验证链 )警告
如果 启用重定向身份验证入口点 = True 对于OAuth2过滤器
web链将无法通过form方法。
备注
记住
anonymous过滤器必须始终是最后一个。保存。
现在可以测试身份验证:
导航到geoserver主页并注销管理帐户。
尝试再次登录,您现在应该能够看到外部谷歌登录表单。
OpenID连接身份验证¶
openid connect身份验证的工作方式与google(和github)身份验证非常相似,唯一的区别是身份验证页面无法为各个端点建议默认值,这些端点必须手动配置。
如果不使用Web登录,则实际上不需要“客户端ID”和“客户端机密”,并且可以用两个组成的值填充(验证仅检查它们是否存在,但它们将仅用于“授权流”,而不用于在客户端为su的情况下执行ogc请求。已自动检索到有效的不记名令牌)。
配置GUI支持OpenID发现文档。如果服务器支持它们,那么提供文档或身份验证服务根目录的路径就足够了,GUI将根据文档内容自动填充:
用户界面还允许设置 Post Logout Redirect URI 它将用于填充 post_logout_redirect_uri 从Geoserver用户界面执行全局注销时的请求参数。OpenID提供程序将使用URI重定向到所需的应用程序页面。
此外,OpenID连接身份验证能够从ID令牌或访问令牌中提取用户角色:
所选属性必须出现在访问令牌或ID令牌中,并且必须是字符串或字符串数组。
从UI中,还可以设置 Response Mode 价值。此字段可以保留为空,但当作为身份提供者的OpenID服务器默认不将授权码作为查询字符串发送时(这是必需的,以允许Geoserver和OpenID正常集成),则需要此字段。
最后,管理员可以允许在Access_Token请求期间通过 Send Client Secret in Token Request 。当客户端应用程序是机密客户端并且可以安全地存储CLIENT_SECRET时,一些OpenID实现需要它用于授权代码流。
使用附加的访问承载令牌进行OpenID连接¶
OpenID连接插件允许使用附加的持有者访问令牌。这通常由自动(即桌面或外部Web服务)用来访问Geoserver REST API。
设置过程如下:
正常设置您的OAuth2 OpenID Connect配置
在OpenID连接配置屏幕(底部)上,确保选中了允许附加的持有者令牌
您不能将ID令牌用作附加的持有者令牌的角色源(见下文)
要使用以下功能,请执行以下操作:
从底层IdP获取访问令牌
将访问令牌附加到您的HTTP请求标头
Authorization: Bearer <token>
验证访问令牌(JWT);
访问令牌用于获取“UserInfo”端点。底层IDP将验证令牌(即签名和过期)
检查令牌的受众是否包含Geoserver配置的客户端ID。这可确保另一个应用程序的访问令牌不会在Geoserver中被不适当地重复使用(参见 AudienceAccessTokenValidator.java )。
的主题是 userinfo 和访问令牌被验证为约为同一个人。OpenID规范建议检查此选项(参见 SubjectTokenValidator.java )。
对于KeyCloak,考虑使用“UserInfo Endpoint”角色源并将Keyloak配置为将组放置在“UserInfo”中。
对于Azure AD,将Azure配置为允许访问MS Graph API(MemberOf)并使用“Microsoft Graph API(Azure AD)”角色源。
为Azure AD配置“Memberof”(“GroupMember.Read.All”权限)访问;
转到您在Azure AD中的应用程序(在门户中)
在左侧,进入“API权限”。
点击“添加权限”
按“Microsoft Graph”
按“委派的权限”
向下滚动到“GroupMember”
选择“组成员.Read.All”
按“添加权限”
在API权限屏幕上,按“授予管理员同意...”文本
这已经通过KeyCloak进行了测试(在 userinfo 端点响应),以及MS Azure AD(来自GraphAPI的组)。这应该适用于其他国内流离失所者-但是,请确保主体和受众令牌验证与他们的令牌一起工作。
如果您不需要不记名令牌功能,建议将其关闭。
Azure AD和ADFS设置¶
要使OpenIdConnect筛选器通过OpenID协议与Azure AD或ADFS服务器一起正常工作,除了其他配置参数外,用户还必须设置 Response Mode 查询(否则,默认情况下,ADFS将返回URL片段)并选中该复选框 Send Client Secret in Token Request (根据令牌请求,CLIENT_SECRET是必需的 Microsoft documentation )。
SSL可信证书¶
使用自定义时 Keystore 或者尝试从非ssh连接访问不受信任或自签名的ssl保护的oauth2提供程序,则需要将证书添加到jvm Keystore .
为此,您可以执行以下步骤:
在这个例子中,我们将
从Google域检索SSL证书:
“访问令牌URI”=https://accounts.google.com/o/oauth2/token因此我们需要信任
https://accounts.google.com或 (accounts.google.com:443)“检查令牌终结点URL”=https://www.googleapis.com/oauth2/v1/tokeninfo因此我们需要信任https://www.googleapis.com或 (www.googleapis.com:443)备注
您需要从oauth2端点上使用的每个不同的https url获取并信任证书。
在本地硬盘上存储SSL证书
将SSL证书添加到Java密钥库
允许JVM检查密钥库中的SSL证书
从Google域中检索SSL证书
使用
openssl命令以转储证书为了
https://accounts.google.comopenssl s_client -connect accounts.google.com:443
为了
https://www.googleapis.comopenssl s_client -connect www.googleapis.com:443
在本地硬盘上存储SSL证书
复制并粘贴这两个部分
-BEGIN CERTIFICATE-,-END CERTIFICATE-把它们保存成两个不同的.cert文件夹备注
.cert文件是纯文本文件,包含-BEGIN CERTIFICATE-,-END CERTIFICATE-部分google.cert(或者你想用什么名字.cert扩展名)
google-apis.cert(或者你想用什么名字.cert扩展名)
将SSL证书添加到Java密钥库
您可以使用java命令
keytool这样地google.cert(或者你想用什么名字.cert扩展名)keytool -import -noprompt -trustcacerts -alias google -file google.cert -keystore ${KEYSTOREFILE} -storepass ${KEYSTOREPASS}
google-apis.cert(或者你想用什么名字.cert扩展名)keytool -import -noprompt -trustcacerts -alias google-apis -file google-apis.cert -keystore ${KEYSTOREFILE} -storepass ${KEYSTOREPASS}
或者,您也可以使用一些图形工具来帮助您管理ssl证书和密钥库,比如 Portecle
java -jar c:\apps\portecle-1.9\portecle.jar
允许JVM检查密钥库中的SSL证书
为了做到这一点,你需要通过
JAVA_OPTION对于您的jvm:-Djavax.net.ssl.trustStore=F:\tmp\keystore.key
重新启动服务器
备注
下面您可以找到一个bash脚本,它简化了密钥库SSL证书的导入。在你方便的时候使用它。
HOST=myhost.example.com
PORT=443
KEYSTOREFILE=dest_keystore
KEYSTOREPASS=changeme
# get the SSL certificate
openssl s_client -connect ${HOST}:${PORT} </dev/null \
| sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ${HOST}.cert
# create a keystore and import certificate
keytool -import -noprompt -trustcacerts \
-alias ${HOST} -file ${HOST}.cert \
-keystore ${KEYSTOREFILE} -storepass ${KEYSTOREPASS}
# verify we've got it.
keytool -list -v -keystore ${KEYSTOREFILE} -storepass ${KEYSTOREPASS} -alias ${HOST}