如何检查“hasRole”在 Java 代码中使用 Spring Security?
如何在Java代码中检查用户权限或权限?例如 - 我想根据角色为用户显示或隐藏按钮。有这样的注释:
@PreAuthorize("hasRole('ROLE_USER')")
How to make it in Java code?像这样的东西:
if(somethingHere.hasRole("ROLE_MANAGER")) {
layout.addComponent(new Button("Edit users"));
}
How to check user authority or permission in Java Code ? For example - I want to show or hide button for user depending on role. There are annotations like:
@PreAuthorize("hasRole('ROLE_USER')")
How to make it in Java code? Something like :
if(somethingHere.hasRole("ROLE_MANAGER")) {
layout.addComponent(new Button("Edit users"));
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(21)
您可以使用 HttpServletRequest 对象的 isUserInRole 方法。
像这样的东西:
you can use the isUserInRole method of the HttpServletRequest object.
something like:
Spring Security 3.0 有这个 API
,您必须在使用它之前注入包装器。
SecurityContextHolderAwareRequestWrapper
Spring Security 3.0 has this API
You'll have to inject the wrapper, before you use it.
SecurityContextHolderAwareRequestWrapper
您可以执行以下操作,而不是使用循环从 UserDetails 查找权限:
Instead of using a loop to find the authority from UserDetails you can do:
您可以检索安全上下文,然后使用它:
You can retrieve the security context and then use that:
您可以实现 hasRole() 方法,如下所示 - (这是在 spring security 3.0.x 上测试的,不确定其他版本。)
You can implement a hasRole() method as below - (This is tested on spring security 3.0.x not sure about other versions.)
我正在使用这个:
I'm using this:
您可以从 AuthorityUtils 类。作为单行检查角色:
警告:这不会检查角色层次结构(如果存在)。
You can get some help from AuthorityUtils class. Checking role as a one-liner:
Caveat: This does not check role hierarchy, if such exists.
大多数答案都遗漏了一些要点:
在 Spring 中,角色和权限不是一回事。请参阅此处了解更多详细信息。
角色名称等于
rolePrefix
+authority
。默认的角色前缀是
ROLE_
,但是,它是可配置的。请参阅此处。因此,正确的角色检查需要尊重角色前缀(如果已配置)。
不幸的是,Spring 中的角色前缀自定义有点hacky,在很多地方,默认前缀
ROLE_
是硬编码的,但除此之外,GrantedAuthorityDefaults
类型的 bean 是在 Spring 上下文中进行检查,如果存在,则尊重其具有的自定义角色前缀。将所有这些信息放在一起,更好的角色检查器实现将类似于:
Most answers are missing some points:
Role and authority are not the same thing in Spring. See here for more details.
Role names are equal to
rolePrefix
+authority
.The default role prefix is
ROLE_
, however, it is configurable. See here.Therefore, a proper role check needs to respect the role prefix if it is configured.
Unfortunately, the role prefix customization in Spring is a bit hacky, in many places the default prefix,
ROLE_
is hardcoded, but in addition to that, a bean of typeGrantedAuthorityDefaults
is checked in the Spring context, and if it exists, the custom role prefix it has is respected.Bringing all this information together, a better role checker implementation would be something like:
下面这两个注释是相同的,“hasRole”会自动添加前缀“ROLE_”。确保您有正确的注释。该角色在 UserDetailsService#loadUserByUsername 中设置。
然后就可以在java代码中获取角色了。
This two annotation below is equal, "hasRole" will auto add prefix "ROLE_". Make sure you have the right annotation. This role is set in UserDetailsService#loadUserByUsername.
then, you can get the role in java code.
当您在服务层中时,不能使用 JoseK 的答案,因为您不想通过对 HTTP 请求的引用引入与 Web 层的耦合。如果您正在考虑解决服务层中的角色问题,Gopi 的答案就是您的最佳选择。
不过,有点啰嗦了。可以通过身份验证直接访问权限。因此,如果您可以假设您有一个用户登录,则执行以下操作:
The answer from JoseK can't be used when your in your service layer, where you don't want to introduce a coupling with the web layer from the reference to the HTTP request. If you're looking into resolving the roles while in the service layer, Gopi's answer is the way to go.
However, it's a bit long winded. The authorities can be accessed right from the Authentication. Hence, if you can assume that you have a user logged in, the following does it:
这是来自另一端的问题,但我想我应该把它放进去,因为我真的必须在互联网上挖掘才能找到答案。
有很多关于如何检查角色的内容,但没有太多说明当您说 hasRole("blah")
HasRole 检查当前经过身份验证的主体的授予权限
时实际检查的是什么。请参阅 hasRole("blah") 实际上意味着 hasAuthority("blah")。
在我见过的例子中,您使用一个实现 UserDetails 的类来执行此操作,该类定义了一个名为 getAuthorities 的方法。在此,您基本上将根据某种逻辑向列表中添加一些
new SimpleGrantedAuthority("some name")
。此列表中的名称是 hasRole 语句检查的内容。我猜想在这种情况下 UserDetails 对象是当前经过身份验证的主体。在身份验证提供程序内部和周围发生了一些神奇的事情,更具体地说是身份验证管理器使这一切发生。
This is sort of coming at the question from the other end but I thought I'd throw it in as I really had to dig on the internet to find this out.
There is a lot of stuff about how to check roles but not much saying what you are actually checking when you say hasRole("blah")
HasRole checks the granted authorities for the currently authenticated principal
So really when you see hasRole("blah") really means hasAuthority("blah").
In the case I've seen, you do this with a class that Implements UserDetails which defines a method called getAuthorities. In this you'll basically add some
new SimpleGrantedAuthority("some name")
to a list based on some logic. The names in this list are the things checked by the hasRole statements.I guess in this context the UserDetails object is the currently authenticated principal. There's some magic that happens in and around authentication providers and more specifically the authentication-manager that makes this happen.
奇怪的是,我认为这个问题没有标准的解决方案,因为 spring-security 访问控制是 基于表达式,而不是基于 java。你可以检查源代码
DefaultMethodSecurityExpressionHandler 看看你是否可以重用他们在那里做的事情
Strangely enough, I don't think there is a standard solution to this problem, as the spring-security access control is expression based, not java-based. you might check the source code for
DefaultMethodSecurityExpressionHandler to see if you can re-use something they are doing there
在我们的项目中,我们使用角色层次结构,而上述大多数答案仅旨在检查特定角色,即仅检查给定的角色,但不检查该角色及其层次结构。
解决方案:
RoleHierarchy 在 spring-security.xml 中定义为 bean。
In our project, we are using a role hierarchy, while most of the above answers only aim at checking for a specific role, i.e. would only check for the role given, but not for that role and up the hierarchy.
A solution for this:
RoleHierarchy is defined as a bean in spring-security.xml.
迟到总比不到好,让我投入我的 2 美分。
在 JSF 世界中,在我的托管 bean 中,我执行了以下操作:
如上所述,我的理解是它可以通过如下冗长的方式完成:
Better late then never, let me put in my 2 cents worth.
In JSF world, within my managed bean, I did the following:
As mentioned above, my understanding is that it can be done the long winded way as followed:
@gouki 的答案是最好的!
只是 Spring 如何真正做到这一点的一个提示。
有一个名为
SecurityContextHolderAwareRequestWrapper
的类,它实现了ServletRequestWrapper
类。SecurityContextHolderAwareRequestWrapper
覆盖isUserInRole
并搜索用户Authentication
(由 Spring 管理)以查找用户是否具有角色。SecurityContextHolderAwareRequestWrapper
代码如下:The @gouki answer is best!
Just a tip of how spring really do this.
There is a class named
SecurityContextHolderAwareRequestWrapper
which implements theServletRequestWrapper
class.The
SecurityContextHolderAwareRequestWrapper
overrides theisUserInRole
and search userAuthentication
(which is managed by Spring) to find if user has a role or not.SecurityContextHolderAwareRequestWrapper
the code is as:可以使用以下方式检查用户角色:
在 SecurityContextHolder 中使用调用静态方法:
身份验证 auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && auth.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_NAME"))) { //做某事}
使用 HttpServletRequest
User Roles can be checked using following ways:
Using call static methods in SecurityContextHolder:
Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && auth.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_NAME"))) { //do something}
Using HttpServletRequest
在您的用户模型上只需添加一个“hasRole”方法,如下所示
我通常使用它来检查经过身份验证的用户是否具有管理员角色,如下所示
On your user model just add a 'hasRole' method like below
I usually use it to check if the authenticated user has the role admin as follows
我在 Java8 的帮助下的方法,通过逗号分隔的角色会给你 true 或 false
My Approach with the help of Java8 , Passing coma separated roles will give you true or false
您可以在 Spring Security 中使用注释
@Secured
或@RolesAllowed
或@PreAuthorise
/@PostAuthorise
。添加此代码
请记住:您需要在配置类前面 。您不需要使用所有 3 个参数
securedEnabled
、jsr250Enabled
、prePostEnabled
。您只需要一个,具体取决于您要使用的注释。然后将角色检查注释放入您的控制器类中。
或者
或者
这是一个教程 https://www.baeldung.com/spring-security-方法安全
You can use the annotation
@Secured
or@RolesAllowed
or@PreAuthorise
/@PostAuthorise
in Spring Security.Remember: You need to add this code
in front of your configure class. You do not need use all of the 3 parameters
securedEnabled
,jsr250Enabled
,prePostEnabled
. You only need one depending on which annotation you want to use.Then put the role check annotation in your controller class.
or
or
Here is a tutorial https://www.baeldung.com/spring-security-method-security
在 Java 代码中,尤其是在 Spring Security 上下文中,您可以以编程方式检查用户角色或权限。以下是如何实现此目标的示例:
In Java code, especially within a Spring Security context, you can check user roles or authorities programmatically. Below is an example of how you might achieve this:
SecurityContextHolder.getContext().getAuthentication()
:这会从SecurityContextHolder
检索Authentication
对象。Authentication
对象代表当前经过身份验证的用户。Optional.ofNullable(...)
:将Authentication
对象包装在Optional
中。如果Authentication
对象不为null
,它将被包装在Optional
中。否则,将创建一个空的Optional
。.map(x -> x.getAuthorities())
:如果Optional
不为空,则映射Authentication
对象向其当局报告。getAuthorities()
方法检索用户授予的权限的集合。.orElse(Collections.emptyList())
:如果Optional
为空(即Authentication
对象为null
或没有权限),这指定要使用的默认值,它是一个空列表 (Collections.emptyList()
)。这样做是为了处理getAuthorities()
返回null
的情况。.stream()
:将权限列表转换为流,使我们能够对元素执行流操作。.anyMatch(x -> x.getAuthority().equals(role))
:检查流中的任何权限是否与指定的角色
匹配。 lambda 表达式 x -> x.getAuthority().equals(role) 用于将每个权限的getAuthority()
值与给定的role
进行比较。如果找到匹配,则会返回true
;否则,它将返回false
。因此,整个代码检查从
SecurityContextHolder
获取的当前用户是否具有与指定角色
匹配的权限。它处理用户未经过身份验证(null
Authentication
对象)或没有权限的情况,在这些情况下返回false
。SecurityContextHolder.getContext().getAuthentication()
: This retrieves theAuthentication
object from theSecurityContextHolder
. TheAuthentication
object represents the currently authenticated user.Optional.ofNullable(...)
: Wraps theAuthentication
object in anOptional
. If theAuthentication
object is notnull
, it will be wrapped in anOptional
. Otherwise, an emptyOptional
will be created..map(x -> x.getAuthorities())
: If theOptional
is not empty, this maps theAuthentication
object to its authorities. ThegetAuthorities()
method retrieves the collection of granted authorities for the user..orElse(Collections.emptyList())
: If theOptional
is empty (i.e., theAuthentication
object isnull
or has no authorities), this specifies a default value to use, which is an empty list (Collections.emptyList()
). This is done to handle the case whengetAuthorities()
returnsnull
..stream()
: Converts the list of authorities to a stream, enabling us to perform stream operations on the elements..anyMatch(x -> x.getAuthority().equals(role))
: Checks if any of the authorities in the stream match the specifiedrole
. The lambda expressionx -> x.getAuthority().equals(role)
is used to compare each authority'sgetAuthority()
value with the givenrole
. If a match is found, it will returntrue
; otherwise, it will returnfalse
.So, the entire code checks if the current user, obtained from
SecurityContextHolder
, has an authority matching the specifiedrole
. It handles the cases where the user is not authenticated (null
Authentication
object) or has no authorities, returningfalse
in those cases.