2.3.6. 保护资源
- 简单的身份验证
-
要强制用户在访问资源前进行身份验证,只需使用
keycloak.protect ()的 no-argument 版本:
app.get( '/complain', keycloak.protect(), complaintHandler );
app.get( '/complain', keycloak.protect(), complaintHandler );
- 基于角色的授权
- 使用当前应用程序的应用程序角色保护资源:
app.get( '/special', keycloak.protect('special'), specialHandler );
app.get( '/special', keycloak.protect('special'), specialHandler );
使用不同应用程序的应用程序角色 保护资源 :
app.get( '/extra-special', keycloak.protect('other-app:special'), extraSpecialHandler );
app.get( '/extra-special', keycloak.protect('other-app:special'), extraSpecialHandler );
使用 realm 角色保护资源的安全:
app.get( '/admin', keycloak.protect( 'realm:admin' ), adminHandler );
app.get( '/admin', keycloak.protect( 'realm:admin' ), adminHandler );
- 基于资源的授权
-
基于资源的授权允许您根据 Keycloak 中定义的一组策略来保护资源及其具体方法/操作,从而从应用程序外部化授权。这可以通过公开可用于保护资源的
keycloak.enforcer方法来实现。*
app.get('/apis/me', keycloak.enforcer('user:profile'), userProfileHandler);
app.get('/apis/me', keycloak.enforcer('user:profile'), userProfileHandler);
keycloak-enforcer 方法以两种模式运行,具体取决于 response_mode 配置选项的值。
app.get('/apis/me', keycloak.enforcer('user:profile', {response_mode: 'token'}), userProfileHandler);
app.get('/apis/me', keycloak.enforcer('user:profile', {response_mode: 'token'}), userProfileHandler);
如果将 response_mode 设置为 令牌,则代表向您的应用程序的 bearer 令牌代表代表您的服务器上获取权限。在这种情况下,Keycloak 使用服务器获得的权限发布新的访问令牌。如果服务器没有响应具有预期权限的令牌,则请求会被拒绝。当使用此模式时,您应该能够从请求获取令牌,如下所示:
当应用程序正在使用会话时,首选此模式,并想从服务器缓存以前的决策,并自动处理刷新令牌。对于充当客户端和服务器的应用程序,这个模式特别有用。
如果将 response_mode 设为 权限 (默认模式),服务器只返回授予的权限列表,而不发出新的访问令牌。除了不发布新令牌外,此方法还通过 请求 公开服务器授予的权限,如下所示:
app.get('/apis/me', keycloak.enforcer('user:profile', {response_mode: 'permissions'}), function (req, res) {
var permissions = req.permissions;
// show user profile
});
app.get('/apis/me', keycloak.enforcer('user:profile', {response_mode: 'permissions'}), function (req, res) {
var permissions = req.permissions;
// show user profile
});
无论正在使用的 response_mode 是什么,keycloak.enforcer 方法将首先尝试检查发送到应用程序的 bearer 令牌的权限。如果 bearer 令牌已采用预期的权限,则不需要与服务器交互来获取决策。这在您的客户端能够在访问受保护资源前从服务器获取访问令牌时特别有用,因此它们可以使用 Keycloak Authorization Services (如增量授权)提供的一些功能,并避免 keycloak.enforcer 被强制访问资源时对服务器的额外请求。
默认情况下,策略强制程序将使用定义为应用程序(例如,通过 keycloak.json)定义的 client_id 来引用 Keycloak 授权服务中的客户端。在这种情况下,客户端不能是公共的,它实际上是一个资源服务器。
如果您的应用程序同时充当公共客户端(frontend)和资源服务器(backend),您可以使用以下配置来引用 Keycloak 中的不同客户端,并带有您要强制的策略:
keycloak.enforcer('user:profile', {resource_server_id: 'my-apiserver'})
keycloak.enforcer('user:profile', {resource_server_id: 'my-apiserver'})
建议您在 Keycloak 中使用不同的客户端来代表您的前端和后端。
如果您使用 Keycloak 授权服务启用了保护的应用程序,且已在 keycloak.json 中定义客户端凭证,您可以将额外声明推送到服务器,并供您的策略使用。为此,您可以定义一个 声明配置选项,它需要一个功能来返回一个带有您要推送的声明的 JSON:
有关如何配置 Keycloak 以保护应用程序资源的详情,请查看授权服务 指南。
- 高级授权
- 要根据 URL 本身的一部分保护资源,假设每个部分都有一个角色:
function protectBySection(token, request) {
return token.hasRole( request.params.section );
}
app.get( '/:section/:page', keycloak.protect( protectBySection ), sectionHandler );
function protectBySection(token, request) {
return token.hasRole( request.params.section );
}
app.get( '/:section/:page', keycloak.protect( protectBySection ), sectionHandler );
高级登录配置:
默认情况下,所有未授权的请求都会被重新定向到 Red Hat Single Sign-On 登录页面,除非您的客户端仅是 bearer。但是,机密或公共客户端可以托管可浏览和 API 端点。要防止在未经身份验证的 API 请求上重定向并返回 HTTP 401,您可以覆盖 redirectToLogin 功能。
例如,此覆盖会检查 URL 是否包含 /api/ 并禁用登录重定向:
Keycloak.prototype.redirectToLogin = function(req) {
var apiReqMatcher = /\/api\//i;
return !apiReqMatcher.test(req.originalUrl || req.url);
};
Keycloak.prototype.redirectToLogin = function(req) {
var apiReqMatcher = /\/api\//i;
return !apiReqMatcher.test(req.originalUrl || req.url);
};