我有一个angular2客户端连接到Play Framework实现的web api。客户端被重定向到keycloak服务器以获取令牌。我在他们的github项目中跟踪了Keycloak示例,客户端正在工作并获得令牌。不幸的是,我找不到已经为Play Framework实现的适配器。到目前为止,我有以下代码来检查用户是否有权访问所请求的资源。
val authzClient = AuthzClient.create()
val request = new EntitlementRequest
val permissions = new PermissionRequest
permissions.setResourceSetName(resourceName)
request.addPermission(permissions)
val entitlementResponse = authzClient.entitlement(token)
.get(resourceServer, request)
我假设如果服务器返回禁用代码,则具有令牌的用户无权访问该资源。我是在正确的轨道上吗?感谢。
更新
我开发了一个自定义操作来检查标头并验证Authorization toke:
import pdi.jwt.{JwtAlgorithm, JwtJson}
import play.api.libs.json.{JsValue, Json}
import play.api.mvc.{ActionRefiner, Request, Result, Results}
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}
case class UserRequest[A](user: User, request: Request[A])
object UserAction extends ActionRefiner[Request, UserRequest] {
private val secret = "xxxxxx"
private val algorithm = JwtAlgorithm.RS256
override protected def refine[A](request: Request[A]): Future[Either[Result, UserRequest[A]]] = Future {
request.headers.get("Authorization") match {
case Some(headerToken) => {
val token = headerToken.substring(7)
JwtJson.decode(token, secret, Seq(algorithm)) match {
case Success(validToken) => {
val tokenJson = Json.parse(validToken.content)
val user = extractUser(tokenJson)
Right(UserRequest(user, request))
}
case Failure(ex) =>
Left(Results.Unauthorized)
}
}
case None => Left(Results.Unauthorized)
}
}
private def extractUser(token: JsValue): User = {
val username = (token \ "preferred_username").as[String]
val firstName = (token \ "given_name").asOpt[String]
val familyName = (token \ "family_name").asOpt[String]
val name = (token \ "name").asOpt[String]
User(username, firstName, familyName, name)
}
}
答案 0 :(得分:1)
这可能是一个较晚的答案,但我希望这对其他人有帮助。 version 4.3之后,权利API已被删除。以下是在不使用适配器的情况下使用Keycloak授权时发现的解决方法。
步骤1:
中定义策略和权限第2步
具有一个内部映射,其中包含哪些HTTP路径属于哪些资源以及每个路径所需的作用域。也可以将其保存在configuration file中。当调用特定路由时,请调用Keycloak令牌终结点以验证访问令牌的声明。
{
"policy-enforcer": {
"user-managed-access" : {},
"enforcement-mode" : "ENFORCING"
"paths": [
{
"path" : "/someUri/*",
"methods" : [
{
"method": "GET",
"scopes" : ["urn:app.com:scopes:view"]
},
{
"method": "POST",
"scopes" : ["urn:app.com:scopes:create"]
}
]
}
]
}
}
如果您使用的是适配器,但未指定路径或资源,则适配器将在内部搜索路径和资源from Keycloak。
第3步:
使用令牌端点来get or evaluate权限。您可以使用response_mode
参数获取最终决定(是否提供访问权限)或检索整个权限。
curl -X POST \
http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \
-H "Authorization: Bearer ${access_token}" \
--data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
--data "permission=Resource A#Scope A"
如果授权请求未映射到任何权限,则将返回403
HTTP状态代码。
答案 1 :(得分:0)
是。我使用权利API和范围实现了一个带有此类检查的测试keycloak-nodejs-example项目。如果用户没有通过检查权限,Keycloak会返回HTTP code 403 FORBIDDEN
。
https://github.com/v-ladynev/keycloak-nodejs-example/blob/master/app.js
无论如何,如果用户有权限,Keycloak应该为GET或PUT请求返回成功的HTTP代码。
您可以使用curl
您使用资源名称。资源有URI
。直接检查URI
会很有趣。但我仍然不知道如何。
您应该始终为Keycloak的每个请求提供access_token
。有时,您可以使用admin
凭据从Keycloak获取此类令牌,使用此URl:auth/realms/master/protocol/openid-connect/token
(master
是预定义域的名称。)
但是对于Entitlement API,您需要一个当前的用户令牌,因为Keycloak应该了解女巫用户评估权限。
您可以使用https://jwt.io/解码RPT
令牌。这只是具有权限的JSON。如果您执行GET授权请求,您将拥有所有权限。对于POST
请求,您将仅评估权限或FORBIDDEN 403
。