我有一个 angular2 客户端连接到由 Play Framework 实现的 Web API。客户端重定向到keycloak服务器获取token。我在他们的 github 项目中遵循了 Keycloak 示例,并且客户端正在工作并获取 token 。不幸的是,我找不到已经为 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)
我假设如果服务器返回禁止代码,则拥有 token 的用户无权访问该资源。我走在正确的轨道上吗?谢谢。
更新:
我开发了一个自定义操作来检查 header 并验证授权 token :
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)
}
}
最佳答案
这可能是一个迟到的答案,但我希望这对其他人有帮助。 version 4.3 之后,授权 API 已被删除。以下是我在没有适配器的情况下使用 Keycloak 授权时发现的解决方法。
第 1 步:
在 Keycloak Admin UI 中定义策略和权限
第 2 步
有一个内部映射,其中包含哪些 HTTP 路径属于哪些资源以及每个路径所需的范围。这也可以保存在configuration file中。当调用特定路由时,调用 Keycloak token 端点来验证访问 token 的声明。
{
"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 步:
使用 token 端点 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 状态代码。
关于playframework - Keycloak资源授权无需适配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42680996/