我有一个问题,我不能解决后,研究了很多。
我有一个客户端(应用程序)和角色,确保应用程序的密钥锁定。
在我的应用程序中,我用.hasRole()-方法检查用户或其他应用程序的角色是否与定义的角色匹配。
问题是我想合并角色并在应用程序中检查它们。
要访问我的应用程序,用户应具有“读”和“写”角色。
在Spring中,hasRole()方法一次只检查一个角色,hasAnyRole()方法检查是否有一个角色匹配。
有没有像hasAllRoles这样的方法?它检查所有的角色是否匹配?
一个请求是仅通过配置解决该问题,但应用程序中实现的方法是hasRole(),因此我认为仅通过应用程序内部Keycloak或www.example.com上的配置无法解决该问题Application.properties
2条答案
按热度按时间pvcm50d11#
最简单的解决方案可能是找到一种方法,向决定“仅使用配置解决该问题”的人解释使用
@PreAuthorize
元数据是更好的解决方案:@PreAuthorize("is(#username) or isNice() or onBehalfOf(#username).can('greet')")
这样的表达式(这取自my tutorials的the most advanced)。@Component
(包括@Service
和@Repository
)的任何方法,而不仅仅是修饰了@RequestMapping
或其偏差之一的@Controller
的公共方法。使用Spel,您可以做您需要做的事情(
read
和write
),还可以根据访问的资源本身(谁创建了它,它链接到什么,...)定义规则试一试:
@EnableMethodSecurity
到你的安全配置类@PreAuthorize("hasRole('read') and hasRole('write')")
7hiiyaii2#
除了@ch4mp所解释的,我还想提供一些其他的原则。
首先是你的问题。你可以用两种方法来处理
hasAllRoles
。第一种是用AuthorizationManagers.allOf
,第二种是用Spel:以及
请继续阅读与您的评论相关的其他建议:
问题是我想合并角色并在应用程序中检查它们。
一颗豆子
将授权逻辑提取到组件中的一种好方法是在表达式中引用授权bean。
例如,您可以执行以下操作:
然后你就可以:
(If我没有弄错,您仍然可以通过这种方法使用@ch4mp的库,只需从Java方法调用库的DSL,而不是在SpEL表达式中调用。)
层次结构
还有一种情况是一些权限隐含其他权限。对于您来说,
message:write
隐含message:read
可能就是这种情况。在这种情况下,您的表达式可以通过在RoleHierarchy
示例中编码这种关系来简化。登录时
有时,在登录时Map权限可能会很有帮助。例如,
USER
的角色可能会转换为message:read
,ADMIN
的角色可能会转换为message:read
和message:write
。也可能会转换为另一种方式。如果客户机授予了message:read
和message:write
,则可能会转换为message:redact
的单个权限。如果在登录时执行此转换,则可以减少请求时的计算量,并且可以在单个位置推断授予的权限。
比如说,我们不去做
或
你会这么做
或
由于您使用的是Keycloak,因此在这种情况下,如果您是资源服务器,则可以考虑使用自定义
JwtGrantedAuthoritiesConverter
;如果您是客户端,则可以考虑使用GrantedAuthoritiesMapper
,将Jwt
授予的权限Map到与您在应用中执行的操作对应的权限。