无法使用 Keycloak 评估基于 Javascript 的策略
Posted
技术标签:
【中文标题】无法使用 Keycloak 评估基于 Javascript 的策略【英文标题】:Can't evaluate Javascript based policy with Keycloak 【发布时间】:2021-12-31 12:53:09 【问题描述】:我正在尝试测试此项目 https://github.com/mposolda/devconf2019-authz/blob/master/cars-realm.json#L191 中定义的基于 javascript 的策略,但每次我尝试访问受保护的资源时,我都会在 keycloak 日志中收到以下错误:
Caused by: java.lang.IllegalStateException: Could not find ScriptEngine for script: Scriptid='null', realmId='cars', name='Only From a Specific Client Address', type='text/javascript', code='var contextAttributes = $evaluation.getContext().getAttributes();
if (contextAttributes.containsValue('kc.client.network.ip_address', '127.0.0.1'))
$evaluation.grant();
', description='Defines that only clients from a specific address can do something'
at org.keycloak.keycloak-services@15.0.2//org.keycloak.scripting.DefaultScriptingProvider.createPreparedScriptEngine(DefaultScriptingProvider.java:106)
at org.keycloak.keycloak-services@15.0.2//org.keycloak.scripting.DefaultScriptingProvider.prepareEvaluatableScript(DefaultScriptingProvider.java:72)
at org.keycloak.keycloak-services@15.0.2//org.keycloak.scripting.DefaultScriptingProvider.prepareEvaluatableScript(DefaultScriptingProvider.java:33)
at org.keycloak.keycloak-authz-policy-common@15.0.2//org.keycloak.authorization.policy.provider.js.JSPolicyProviderFactory.lambda$getEvaluatableScript$0(JSPolicyProviderFactory.java:109)
at org.keycloak.keycloak-authz-policy-common@15.0.2//org.keycloak.authorization.policy.provider.js.ScriptCache.lambda$computeIfAbsent$0(ScriptCache.java:80)
at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1224)
at org.keycloak.keycloak-authz-policy-common@15.0.2//org.keycloak.authorization.policy.provider.js.ScriptCache.computeIfAbsent(ScriptCache.java:80)
at org.keycloak.keycloak-authz-policy-common@15.0.2//org.keycloak.authorization.policy.provider.js.JSPolicyProviderFactory.getEvaluatableScript(JSPolicyProviderFactory.java:106)
at org.keycloak.keycloak-authz-policy-common@15.0.2//org.keycloak.authorization.policy.provider.js.JSPolicyProvider.evaluate(JSPolicyProvider.java:46)
at org.keycloak.keycloak-authz-policy-common@15.0.2//org.keycloak.authorization.policy.provider.aggregated.AggregatePolicyProvider.evaluate(AggregatePolicyProvider.java:66)
at org.keycloak.keycloak-authz-policy-common@15.0.2//org.keycloak.authorization.policy.provider.aggregated.AggregatePolicyProvider.evaluate(AggregatePolicyProvider.java:66)
at org.keycloak.keycloak-authz-policy-common@15.0.2//org.keycloak.authorization.policy.provider.permission.AbstractPermissionProvider.evaluate(AbstractPermissionProvider.java:56)
at org.keycloak.keycloak-authz-policy-common@15.0.2//org.keycloak.authorization.policy.provider.permission.ScopePolicyProvider.evaluate(ScopePolicyProvider.java:52)
at org.keycloak.keycloak-server-spi-private@15.0.2//org.keycloak.authorization.policy.evaluation.DefaultPolicyEvaluator.lambda$createPolicyEvaluator$0(DefaultPolicyEvaluator.java:116)
at org.keycloak.keycloak-model-infinispan@15.0.2//org.keycloak.models.cache.infinispan.authorization.StoreFactoryCacheSession$PolicyCache.cacheQuery(StoreFactoryCacheSession.java:1098)
at org.keycloak.keycloak-model-infinispan@15.0.2//org.keycloak.models.cache.infinispan.authorization.StoreFactoryCacheSession$PolicyCache.cacheQuery(StoreFactoryCacheSession.java:1073)
at org.keycloak.keycloak-model-infinispan@15.0.2//org.keycloak.models.cache.infinispan.authorization.StoreFactoryCacheSession$PolicyCache.findByScopeIds(StoreFactoryCacheSession.java:1045)
at org.keycloak.keycloak-server-spi-private@15.0.2//org.keycloak.authorization.AuthorizationProvider$3.findByScopeIds(AuthorizationProvider.java:430)
at org.keycloak.keycloak-server-spi-private@15.0.2//org.keycloak.authorization.policy.evaluation.DefaultPolicyEvaluator.evaluate(DefaultPolicyEvaluator.java:86)
at org.keycloak.keycloak-server-spi-private@15.0.2//org.keycloak.authorization.permission.evaluator.UnboundedPermissionEvaluator.lambda$evaluate$0(UnboundedPermissionEvaluator.java:49)
at org.keycloak.keycloak-server-spi-private@15.0.2//org.keycloak.authorization.permission.Permissions.lambda$all$1(Permissions.java:87)
at java.base/java.util.function.Consumer.lambda$andThen$0(Consumer.java:65)
at java.base/java.util.function.Consumer.lambda$andThen$0(Consumer.java:65)
at org.keycloak.keycloak-model-infinispan@15.0.2//org.keycloak.models.cache.infinispan.authorization.StoreFactoryCacheSession$ResourceCache$1.accept(StoreFactoryCacheSession.java:678)
at org.keycloak.keycloak-model-infinispan@15.0.2//org.keycloak.models.cache.infinispan.authorization.StoreFactoryCacheSession$ResourceCache$1.accept(StoreFactoryCacheSession.java:673)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at org.keycloak.keycloak-server-spi-private@15.0.2//org.keycloak.utils.ClosingStream.forEach(ClosingStream.java:128)
at org.keycloak.keycloak-model-jpa@15.0.2//org.keycloak.authorization.jpa.store.JPAResourceStore.findByOwnerFilter(JPAResourceStore.java:136)
at org.keycloak.keycloak-model-jpa@15.0.2//org.keycloak.authorization.jpa.store.JPAResourceStore.findByOwner(JPAResourceStore.java:101)
at org.keycloak.keycloak-model-infinispan@15.0.2//org.keycloak.models.cache.infinispan.authorization.StoreFactoryCacheSession$ResourceCache.lambda$findByOwner$7(StoreFactoryCacheSession.java:673)
at org.keycloak.keycloak-model-infinispan@15.0.2//org.keycloak.models.cache.infinispan.authorization.StoreFactoryCacheSession$ResourceCache.cacheQuery(StoreFactoryCacheSession.java:845)
at org.keycloak.keycloak-model-infinispan@15.0.2//org.keycloak.models.cache.infinispan.authorization.StoreFactoryCacheSession$ResourceCache.cacheQuery(StoreFactoryCacheSession.java:830)
at org.keycloak.keycloak-model-infinispan@15.0.2//org.keycloak.models.cache.infinispan.authorization.StoreFactoryCacheSession$ResourceCache.findByOwner(StoreFactoryCacheSession.java:671)
at org.keycloak.keycloak-server-spi-private@15.0.2//org.keycloak.authorization.AuthorizationProvider$4.findByOwner(AuthorizationProvider.java:501)
at org.keycloak.keycloak-server-spi-private@15.0.2//org.keycloak.authorization.permission.Permissions.all(Permissions.java:85)
at org.keycloak.keycloak-server-spi-private@15.0.2//org.keycloak.authorization.permission.evaluator.UnboundedPermissionEvaluator.evaluate(UnboundedPermissionEvaluator.java:48)
为了使这个例子正常工作,我还需要做些什么吗?
Keycloak 版本:15.0.2 Java版本:15
谢谢!
【问题讨论】:
keycloak服务器使用什么版本的java?在 Java 15 中删除了 Rhino。如果服务器使用 Java 15+,这是预期的行为。如果是这种情况,那么我们可以降级到 Java this question。 我使用的是 Java 15,切换回 11 确实解决了问题!感谢您的帮助。 【参考方案1】:当我们查看日志消息的第一行时:
Could not find ScriptEngine for script: Script ... type='text/javascript'...
我们看到 keycloak 无法加载 javascript 脚本引擎。
由于 Java >= 15,JVM 没有提供任何 javascript 引擎(请参阅JEP 372)。这就是keycloak找不到javascript引擎的原因。
我看到了两种可能的解决方案:
通过一些 3rd 方库提供 javascript 引擎(详情请参阅 this question by Paul Taylor),或 将 Java 降级到【讨论】:
以上是关于无法使用 Keycloak 评估基于 Javascript 的策略的主要内容,如果未能解决你的问题,请参考以下文章
在反向代理后面使用 Keycloak:无法打开管理员登录页面,因为内容混合