如何检查“hasRole”在 Java 代码中使用 Spring Security?

发布于 2024-09-05 15:17:57 字数 287 浏览 3 评论 0原文

如何在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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(21

请持续率性 2024-09-12 15:17:57

您可以使用 HttpServletRequest 对象的 isUserInRole 方法。

像这样的东西:

public String createForm(HttpSession session, HttpServletRequest request,  ModelMap   modelMap) {


    if (request.isUserInRole("ROLE_ADMIN")) {
        // code here
    }
}

you can use the isUserInRole method of the HttpServletRequest object.

something like:

public String createForm(HttpSession session, HttpServletRequest request,  ModelMap   modelMap) {


    if (request.isUserInRole("ROLE_ADMIN")) {
        // code here
    }
}
雨后彩虹 2024-09-12 15:17:57

Spring Security 3.0 有这个 API

SecurityContextHolderAwareRequestWrapper.isUserInRole(String role)

,您必须在使用它之前注入包装器。

SecurityContextHolderAwareRequestWrapper

Spring Security 3.0 has this API

SecurityContextHolderAwareRequestWrapper.isUserInRole(String role)

You'll have to inject the wrapper, before you use it.

SecurityContextHolderAwareRequestWrapper

放肆 2024-09-12 15:17:57

您可以执行以下操作,而不是使用循环从 UserDetails 查找权限:

Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
boolean authorized = authorities.contains(new SimpleGrantedAuthority("ROLE_ADMIN"));

Instead of using a loop to find the authority from UserDetails you can do:

Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
boolean authorized = authorities.contains(new SimpleGrantedAuthority("ROLE_ADMIN"));
故事灯 2024-09-12 15:17:57

您可以检索安全上下文,然后使用它:

    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.context.SecurityContext;
    import org.springframework.security.core.context.SecurityContextHolder;

    protected boolean hasRole(String role) {
        // get security context from thread local
        SecurityContext context = SecurityContextHolder.getContext();
        if (context == null)
            return false;

        Authentication authentication = context.getAuthentication();
        if (authentication == null)
            return false;

        for (GrantedAuthority auth : authentication.getAuthorities()) {
            if (role.equals(auth.getAuthority()))
                return true;
        }

        return false;
    }

You can retrieve the security context and then use that:

    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.context.SecurityContext;
    import org.springframework.security.core.context.SecurityContextHolder;

    protected boolean hasRole(String role) {
        // get security context from thread local
        SecurityContext context = SecurityContextHolder.getContext();
        if (context == null)
            return false;

        Authentication authentication = context.getAuthentication();
        if (authentication == null)
            return false;

        for (GrantedAuthority auth : authentication.getAuthorities()) {
            if (role.equals(auth.getAuthority()))
                return true;
        }

        return false;
    }
扭转时空 2024-09-12 15:17:57

您可以实现 hasRole() 方法,如下所示 - (这是在 spring security 3.0.x 上测试的,不确定其他版本。)

  protected final boolean hasRole(String role) {
    boolean hasRole = false;
    UserDetails userDetails = getUserDetails();
    if (userDetails != null) {
      Collection<GrantedAuthority> authorities = userDetails.getAuthorities();
      if (isRolePresent(authorities, role)) {
        hasRole = true;
      }
    } 
    return hasRole;
  }
  /**
   * Get info about currently logged in user
   * @return UserDetails if found in the context, null otherwise
   */
  protected UserDetails getUserDetails() {
    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    UserDetails userDetails = null;
    if (principal instanceof UserDetails) {
      userDetails = (UserDetails) principal;
    }
    return userDetails;
  }
  /**
   * Check if a role is present in the authorities of current user
   * @param authorities all authorities assigned to current user
   * @param role required authority
   * @return true if role is present in list of authorities assigned to current user, false otherwise
   */
  private boolean isRolePresent(Collection<GrantedAuthority> authorities, String role) {
    boolean isRolePresent = false;
    for (GrantedAuthority grantedAuthority : authorities) {
      isRolePresent = grantedAuthority.getAuthority().equals(role);
      if (isRolePresent) break;
    }
    return isRolePresent;
  }

You can implement a hasRole() method as below - (This is tested on spring security 3.0.x not sure about other versions.)

  protected final boolean hasRole(String role) {
    boolean hasRole = false;
    UserDetails userDetails = getUserDetails();
    if (userDetails != null) {
      Collection<GrantedAuthority> authorities = userDetails.getAuthorities();
      if (isRolePresent(authorities, role)) {
        hasRole = true;
      }
    } 
    return hasRole;
  }
  /**
   * Get info about currently logged in user
   * @return UserDetails if found in the context, null otherwise
   */
  protected UserDetails getUserDetails() {
    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    UserDetails userDetails = null;
    if (principal instanceof UserDetails) {
      userDetails = (UserDetails) principal;
    }
    return userDetails;
  }
  /**
   * Check if a role is present in the authorities of current user
   * @param authorities all authorities assigned to current user
   * @param role required authority
   * @return true if role is present in list of authorities assigned to current user, false otherwise
   */
  private boolean isRolePresent(Collection<GrantedAuthority> authorities, String role) {
    boolean isRolePresent = false;
    for (GrantedAuthority grantedAuthority : authorities) {
      isRolePresent = grantedAuthority.getAuthority().equals(role);
      if (isRolePresent) break;
    }
    return isRolePresent;
  }
小梨窩很甜 2024-09-12 15:17:57

我正在使用这个:

@RequestMapping(method = RequestMethod.GET)
public void welcome(SecurityContextHolderAwareRequestWrapper request) {
    boolean b = request.isUserInRole("ROLE_ADMIN");
    System.out.println("ROLE_ADMIN=" + b);

    boolean c = request.isUserInRole("ROLE_USER");
    System.out.println("ROLE_USER=" + c);
}

I'm using this:

@RequestMapping(method = RequestMethod.GET)
public void welcome(SecurityContextHolderAwareRequestWrapper request) {
    boolean b = request.isUserInRole("ROLE_ADMIN");
    System.out.println("ROLE_ADMIN=" + b);

    boolean c = request.isUserInRole("ROLE_USER");
    System.out.println("ROLE_USER=" + c);
}
夏尔 2024-09-12 15:17:57

您可以从 AuthorityUtils 类。作为单行检查角色:

if (AuthorityUtils.authorityListToSet(SecurityContextHolder.getContext().getAuthentication().getAuthorities()).contains("ROLE_MANAGER")) {
    /* ... */
}

警告:这不会检查角色层次结构(如果存在)。

You can get some help from AuthorityUtils class. Checking role as a one-liner:

if (AuthorityUtils.authorityListToSet(SecurityContextHolder.getContext().getAuthentication().getAuthorities()).contains("ROLE_MANAGER")) {
    /* ... */
}

Caveat: This does not check role hierarchy, if such exists.

深海少女心 2024-09-12 15:17:57

大多数答案都遗漏了一些要点:

  1. 在 Spring 中,角色和权限不是一回事。请参阅此处了解更多详细信息。

  2. 角色名称等于 rolePrefix + authority

  3. 默认的角色前缀是ROLE_,但是,它是可配置的。请参阅此处

因此,正确的角色检查需要尊重角色前缀(如果已配置)。

不幸的是,Spring 中的角色前缀自定义有点hacky,在很多地方,默认前缀 ROLE_ 是硬编码的,但除此之外,GrantedAuthorityDefaults 类型的 bean 是在 Spring 上下文中进行检查,如果存在,则尊重其具有的自定义角色前缀。

将所有这些信息放在一起,更好的角色检查器实现将类似于:

@Component
public class RoleChecker {

    @Autowired(required = false)
    private GrantedAuthorityDefaults grantedAuthorityDefaults;

    public boolean hasRole(String role) {
        String rolePrefix = grantedAuthorityDefaults != null ? grantedAuthorityDefaults.getRolePrefix() : "ROLE_";
        return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
                .map(Authentication::getAuthorities)
                .map(Collection::stream)
                .orElse(Stream.empty())
                .map(GrantedAuthority::getAuthority)
                .map(authority -> rolePrefix + authority)
                .anyMatch(role::equals);
    }
}

Most answers are missing some points:

  1. Role and authority are not the same thing in Spring. See here for more details.

  2. Role names are equal to rolePrefix + authority.

  3. 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 type GrantedAuthorityDefaults 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:

@Component
public class RoleChecker {

    @Autowired(required = false)
    private GrantedAuthorityDefaults grantedAuthorityDefaults;

    public boolean hasRole(String role) {
        String rolePrefix = grantedAuthorityDefaults != null ? grantedAuthorityDefaults.getRolePrefix() : "ROLE_";
        return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
                .map(Authentication::getAuthorities)
                .map(Collection::stream)
                .orElse(Stream.empty())
                .map(GrantedAuthority::getAuthority)
                .map(authority -> rolePrefix + authority)
                .anyMatch(role::equals);
    }
}
书间行客 2024-09-12 15:17:57

下面这两个注释是相同的,“hasRole”会自动添加前缀“ROLE_”。确保您有正确的注释。该角色在 UserDetailsS​​ervice#loadUserByUsername 中设置。

@PreAuthorize("hasAuthority('ROLE_user')")
@PreAuthorize("hasRole('user')")

然后就可以在java代码中获取角色了。

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_user"))){
    System.out.println("user role2");
}

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.

@PreAuthorize("hasAuthority('ROLE_user')")
@PreAuthorize("hasRole('user')")

then, you can get the role in java code.

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_user"))){
    System.out.println("user role2");
}
琉璃梦幻 2024-09-12 15:17:57

当您在服务层中时,不能使用 JoseK 的答案,因为您不想通过对 HTTP 请求的引用引入与 Web 层的耦合。如果您正在考虑解决服务层中的角色问题,Gopi 的答案就是您的最佳选择。

不过,有点啰嗦了。可以通过身份验证直接访问权限。因此,如果您可以假设您有一个用户登录,则执行以下操作:

/**
 * @return true if the user has one of the specified roles.
 */
protected boolean hasRole(String[] roles) {
    boolean result = false;
    for (GrantedAuthority authority : SecurityContextHolder.getContext().getAuthentication().getAuthorities()) {
        String userRole = authority.getAuthority();
        for (String role : roles) {
            if (role.equals(userRole)) {
                result = true;
                break;
            }
        }

        if (result) {
            break;
        }
    }

    return result;
}

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:

/**
 * @return true if the user has one of the specified roles.
 */
protected boolean hasRole(String[] roles) {
    boolean result = false;
    for (GrantedAuthority authority : SecurityContextHolder.getContext().getAuthentication().getAuthorities()) {
        String userRole = authority.getAuthority();
        for (String role : roles) {
            if (role.equals(userRole)) {
                result = true;
                break;
            }
        }

        if (result) {
            break;
        }
    }

    return result;
}
沩ん囻菔务 2024-09-12 15:17:57

这是来自另一端的问题,但我想我应该把它放进去,因为我真的必须在互联网上挖掘才能找到答案。

有很多关于如何检查角色的内容,但没有太多说明当您说 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.

夏日浅笑〃 2024-09-12 15:17:57

奇怪的是,我认为这个问题没有标准的解决方案,因为 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

内心旳酸楚 2024-09-12 15:17:57

在我们的项目中,我们使用角色层次结构,而上述大多数答案仅旨在检查特定角色,即仅检查给定的角色,但不检查该角色及其层次结构。

解决方案:

@Component
public class SpringRoleEvaluator {

@Resource(name="roleHierarchy")
private RoleHierarchy roleHierarchy;

public boolean hasRole(String role) {
    UserDetails dt = AuthenticationUtils.getSessionUserDetails();

    for (GrantedAuthority auth: roleHierarchy.getReachableGrantedAuthorities(dt.getAuthorities())) {
        if (auth.toString().equals("ROLE_"+role)) {
            return true;
        }
    }
    return false;
}

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:

@Component
public class SpringRoleEvaluator {

@Resource(name="roleHierarchy")
private RoleHierarchy roleHierarchy;

public boolean hasRole(String role) {
    UserDetails dt = AuthenticationUtils.getSessionUserDetails();

    for (GrantedAuthority auth: roleHierarchy.getReachableGrantedAuthorities(dt.getAuthorities())) {
        if (auth.toString().equals("ROLE_"+role)) {
            return true;
        }
    }
    return false;
}

RoleHierarchy is defined as a bean in spring-security.xml.

檐上三寸雪 2024-09-12 15:17:57

迟到总比不到好,让我投入我的 2 美分。

在 JSF 世界中,在我的托管 bean 中,我执行了以下操作:


HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
SecurityContextHolderAwareRequestWrapper sc = new SecurityContextHolderAwareRequestWrapper(req, "");

如上所述,我的理解是它可以通过如下冗长的方式完成:


Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserDetails userDetails = null;
if (principal instanceof UserDetails) {
    userDetails = (UserDetails) principal;
    Collection  authorities = userDetails.getAuthorities();
}

Better late then never, let me put in my 2 cents worth.

In JSF world, within my managed bean, I did the following:


HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
SecurityContextHolderAwareRequestWrapper sc = new SecurityContextHolderAwareRequestWrapper(req, "");

As mentioned above, my understanding is that it can be done the long winded way as followed:


Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserDetails userDetails = null;
if (principal instanceof UserDetails) {
    userDetails = (UserDetails) principal;
    Collection  authorities = userDetails.getAuthorities();
}
帅哥哥的热头脑 2024-09-12 15:17:57

@gouki 的答案是最好的!

只是 Spring 如何真正做到这一点的一个提示。

有一个名为 SecurityContextHolderAwareRequestWrapper 的类,它实现了 ServletRequestWrapper 类。

SecurityContextHolderAwareRequestWrapper 覆盖 isUserInRole 并搜索用户 Authentication(由 Spring 管理)以查找用户是否具有角色。

SecurityContextHolderAwareRequestWrapper 代码如下:

    @Override
    public boolean isUserInRole(String role) {
        return isGranted(role);
    }

 private boolean isGranted(String role) {
        Authentication auth = getAuthentication();

        if( rolePrefix != null ) {
            role = rolePrefix + role;
        }

        if ((auth == null) || (auth.getPrincipal() == null)) {
            return false;
        }

        Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();

        if (authorities == null) {
            return false;
        }

        //This is the loop which do actual search
        for (GrantedAuthority grantedAuthority : authorities) {
            if (role.equals(grantedAuthority.getAuthority())) {
                return true;
            }
        }

        return false;
    }

The @gouki answer is best!

Just a tip of how spring really do this.

There is a class named SecurityContextHolderAwareRequestWrapper which implements the ServletRequestWrapper class.

The SecurityContextHolderAwareRequestWrapper overrides the isUserInRole and search user Authentication (which is managed by Spring) to find if user has a role or not.

SecurityContextHolderAwareRequestWrapper the code is as:

    @Override
    public boolean isUserInRole(String role) {
        return isGranted(role);
    }

 private boolean isGranted(String role) {
        Authentication auth = getAuthentication();

        if( rolePrefix != null ) {
            role = rolePrefix + role;
        }

        if ((auth == null) || (auth.getPrincipal() == null)) {
            return false;
        }

        Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();

        if (authorities == null) {
            return false;
        }

        //This is the loop which do actual search
        for (GrantedAuthority grantedAuthority : authorities) {
            if (role.equals(grantedAuthority.getAuthority())) {
                return true;
            }
        }

        return false;
    }
一场信仰旅途 2024-09-12 15:17:57

可以使用以下方式检查用户角色:

  1. 在 SecurityContextHolder 中使用调用静态方法:

    身份验证 auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null && auth.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_NAME"))) { //做某事}

  2. 使用 HttpServletRequest

@GetMapping("/users")
public String getUsers(HttpServletRequest request) {
    if (request.isUserInRole("ROLE_NAME")) {
      
    }

User Roles can be checked using following ways:

  1. 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}

  2. Using HttpServletRequest

@GetMapping("/users")
public String getUsers(HttpServletRequest request) {
    if (request.isUserInRole("ROLE_NAME")) {
      
    }

勿忘心安 2024-09-12 15:17:57

在您的用户模型上只需添加一个“hasRole”方法,如下所示

public boolean hasRole(String auth) {
    for (Role role : roles) {
        if (role.getName().equals(auth)) { return true; }
    }
    return false;
}

我通常使用它来检查经过身份验证的用户是否具有管理员角色,如下所示

Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); // This gets the authentication
User authUser = (User) authentication.getPrincipal(); // This gets the logged in user
authUser.hasRole("ROLE_ADMIN") // This returns true or false

On your user model just add a 'hasRole' method like below

public boolean hasRole(String auth) {
    for (Role role : roles) {
        if (role.getName().equals(auth)) { return true; }
    }
    return false;
}

I usually use it to check if the authenticated user has the role admin as follows

Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); // This gets the authentication
User authUser = (User) authentication.getPrincipal(); // This gets the logged in user
authUser.hasRole("ROLE_ADMIN") // This returns true or false

我在 Java8 的帮助下的方法,通过逗号分隔的角色会给你 true 或 false

    public static Boolean hasAnyPermission(String permissions){
    Boolean result = false;
    if(permissions != null && !permissions.isEmpty()){
        String[] rolesArray = permissions.split(",");
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        for (String role : rolesArray) {
            boolean hasUserRole = authentication.getAuthorities().stream().anyMatch(r -> r.getAuthority().equals(role));
            if (hasUserRole) {
                result = true;
                break;
            }
        }
    }
    return result;
}

My Approach with the help of Java8 , Passing coma separated roles will give you true or false

    public static Boolean hasAnyPermission(String permissions){
    Boolean result = false;
    if(permissions != null && !permissions.isEmpty()){
        String[] rolesArray = permissions.split(",");
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        for (String role : rolesArray) {
            boolean hasUserRole = authentication.getAuthorities().stream().anyMatch(r -> r.getAuthority().equals(role));
            if (hasUserRole) {
                result = true;
                break;
            }
        }
    }
    return result;
}
枫林﹌晚霞¤ 2024-09-12 15:17:57

您可以在 Spring Security 中使用注释 @Secured@RolesAllowed@PreAuthorise / @PostAuthorise

添加此代码

@Configuration
@EnableGlobalMethodSecurity(
    securedEnabled = true, 
    jsr250Enabled = true, 
    prePostEnabled = true
)
public class MyConfig extends WebSecurityConfigurerAdapter{
}

请记住:您需要在配置类前面 。您不需要使用所有 3 个参数 securedEnabledjsr250EnabledprePostEnabled。您只需要一个,具体取决于您要使用的注释。

然后将角色检查注释放入您的控制器类中。

@Secured("ROLE_admin")
@GetMapping("/hello")
public String hello(){
    return "hello";
}

或者

@RolesAllowed("ROLE_admin")
@GetMapping("/hello")
public String hello(){
    return "hello";
}

或者

@PreAuthorize("hasRole('ROLE_user')")
@GetMapping("/hello")
public String hello(){
    return "hello";
}

这是一个教程 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

@Configuration
@EnableGlobalMethodSecurity(
    securedEnabled = true, 
    jsr250Enabled = true, 
    prePostEnabled = true
)
public class MyConfig extends WebSecurityConfigurerAdapter{
}

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.

@Secured("ROLE_admin")
@GetMapping("/hello")
public String hello(){
    return "hello";
}

or

@RolesAllowed("ROLE_admin")
@GetMapping("/hello")
public String hello(){
    return "hello";
}

or

@PreAuthorize("hasRole('ROLE_user')")
@GetMapping("/hello")
public String hello(){
    return "hello";
}

Here is a tutorial https://www.baeldung.com/spring-security-method-security

坐在坟头思考人生 2024-09-12 15:17:57

在 Java 代码中,尤其是在 Spring Security 上下文中,您可以以编程方式检查用户角色或权限。以下是如何实现此目标的示例:

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

// Your code...

// Get the currently authenticated user
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

// Check if the user has a specific role
if (authentication != null && authentication.getPrincipal() instanceof UserDetails) {
    UserDetails userDetails = (UserDetails) authentication.getPrincipal();

    if (userDetails.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_MANAGER"))) {
        // User has the ROLE_MANAGER role, so you can show the button
        layout.addComponent(new Button("Edit users"));
    }
}

// Your code...

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:

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

// Your code...

// Get the currently authenticated user
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

// Check if the user has a specific role
if (authentication != null && authentication.getPrincipal() instanceof UserDetails) {
    UserDetails userDetails = (UserDetails) authentication.getPrincipal();

    if (userDetails.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_MANAGER"))) {
        // User has the ROLE_MANAGER role, so you can show the button
        layout.addComponent(new Button("Edit users"));
    }
}

// Your code...
很酷不放纵 2024-09-12 15:17:57
public static Boolean isUserInRole(String role) {
    return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
            .map(x->x.getAuthorities())
            .orElse(Collections.emptyList())
            .stream()
            .anyMatch(x->x.getAuthority()
                    .equals(role));
            
}

ChatGPT 逐步说明:

  1. SecurityContextHolder.getContext().getAuthentication():这会从 SecurityContextHolder 检索 Authentication 对象。 Authentication 对象代表当前经过身份验证的用户。

  2. Optional.ofNullable(...):将 Authentication 对象包装在 Optional 中。如果 Authentication 对象不为 null,它将被包装在 Optional 中。否则,将创建一个空的Optional

  3. .map(x -> x.getAuthorities()):如果 Optional 不为空,则映射 Authentication 对象向其当局报告。 getAuthorities() 方法检索用户授予的权限的集合。

  4. .orElse(Collections.emptyList()):如果 Optional 为空(即 Authentication 对象为 null 或没有权限),这指定要使用的默认值,它是一个空列表 (Collections.emptyList())。这样做是为了处理 getAuthorities() 返回 null 的情况。

  5. .stream():将权限列表转换为流,使我们能够对元素执行流操作。

  6. .anyMatch(x -> x.getAuthority().equals(role)):检查流中的任何权限是否与指定的角色匹配。 lambda 表达式 x -> x.getAuthority().equals(role) 用于将每个权限的 getAuthority() 值与给定的role 进行比较。如果找到匹配,则会返回true;否则,它将返回false

因此,整个代码检查从 SecurityContextHolder 获取的当前用户是否具有与指定角色匹配的权限。它处理用户未经过身份验证(null Authentication 对象)或没有权限的情况,在这些情况下返回 false

public static Boolean isUserInRole(String role) {
    return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
            .map(x->x.getAuthorities())
            .orElse(Collections.emptyList())
            .stream()
            .anyMatch(x->x.getAuthority()
                    .equals(role));
            
}

ChatGPT explanation step by step:

  1. SecurityContextHolder.getContext().getAuthentication(): This retrieves the Authentication object from the SecurityContextHolder. The Authentication object represents the currently authenticated user.

  2. Optional.ofNullable(...): Wraps the Authentication object in an Optional. If the Authentication object is not null, it will be wrapped in an Optional. Otherwise, an empty Optional will be created.

  3. .map(x -> x.getAuthorities()): If the Optional is not empty, this maps the Authentication object to its authorities. The getAuthorities() method retrieves the collection of granted authorities for the user.

  4. .orElse(Collections.emptyList()): If the Optional is empty (i.e., the Authentication object is null 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 when getAuthorities() returns null.

  5. .stream(): Converts the list of authorities to a stream, enabling us to perform stream operations on the elements.

  6. .anyMatch(x -> x.getAuthority().equals(role)): Checks if any of the authorities in the stream match the specified role. The lambda expression x -> x.getAuthority().equals(role) is used to compare each authority's getAuthority() value with the given role. If a match is found, it will return true; otherwise, it will return false.

So, the entire code checks if the current user, obtained from SecurityContextHolder, has an authority matching the specified role. It handles the cases where the user is not authenticated (null Authentication object) or has no authorities, returning false in those cases.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文