如何使用Spring Security实现用户-角色-资源的权限控制

 更新时间:2024年10月15日 11:01:35   作者:Takumilovexu  
文章介绍了如何通过SpringSecurity实现用户-角色-资源的权限管理,包括基于角色的请求控制、加载用户角色信息、角色与资源的关联等步骤,同时,提供了一些测试场景,以验证权限控制是否正确,感兴趣的朋友跟随小编一起看看吧

在Web应用的开发中,权限管理是必不可少的一环。继上次分享了基于 用户-权限-资源的权限控制后,这次我们来探讨如何通过Spring Security实现 用户-角色-资源的权限管理。

一、基于角色的请求控制

首先,我们需要根据不同的资源路径设置相应的角色要求。以下是安全配置的代码:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    // 开启授权保护
    http.authorizeHttpRequests(authorize -> authorize
            // 所有 /user/** 路径下的请求需要 ADMIN 角色
            .requestMatchers("/user/**").hasRole("ADMIN")
            // 对所有请求开启授权保护
            .anyRequest()
            // 已认证的请求自动被授权
            .authenticated());
    // 其他配置省略...
}

在这段代码中,我们通过hasRole("ADMIN")方法,指定访问/user/**路径的请求需要具备ADMIN角色。这样,我们就实现了基于角色的资源访问控制。

二、加载用户角色信息

接下来,我们需要为用户加载其对应的角色信息。在Spring Security中,可以通过实现UserDetailsService接口的loadUserByUsername方法:

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
    lambdaQueryWrapper.eq(User::getUsername, username);
    User user = userMapper.selectOne(lambdaQueryWrapper);
    if (user == null) {
        throw new UsernameNotFoundException(username);
    } else {
        return org.springframework.security.core.userdetails.User.withUsername(user.getUsername())
                .password(user.getPassword())
                .disabled(!user.getEnabled())
            	// 设置用户的凭据是否过期,false 表示凭据未过期
                .credentialsExpired(false)
            	// 设置账户是否被锁定,false 表示账户未锁定
                .accountLocked(false)
                // 为用户分配 ADMIN 角色
                .roles("ADMIN")
                .build();
    }
}

在这个方法中,我们:

  • 从数据库中根据用户名查询用户信息。
  • 如果用户存在,使用User.withUsername()方法构建一个UserDetails对象。
  • 通过.roles("ADMIN")方法为用户分配ADMIN角色。

需要注意的是,Spring Security在处理角色时,会自动为角色名添加"ROLE_"前缀。因此,"ADMIN"角色实际上对应权限"ROLE_ADMIN"

三、角色与资源的关联

通过上述配置,我们实现了以下功能:

  • 用户:通过数据库加载,包含用户名、密码、是否启用等信息。
  • 角色:为用户分配特定的角色,例如ADMIN
  • 资源:指定哪些URL路径需要哪些角色才能访问。

当用户尝试访问受保护的资源时,Spring Security会根据用户的角色信息决定是否授权。

四、测试角色权限控制

以下是一些测试场景,帮助验证我们的权限控制是否正确。

1. 未登录用户访问受保护资源

当未登录的用户尝试访问/user/list时,会被重定向到登录页面,提示需要先进行身份认证。

2. 登录用户访问受保护资源

使用具备ADMIN角色的用户登录后,尝试访问/user/list,应当能够正常访问。

3. 角色不足的用户访问受保护资源(把前面改成.roles(“USER”))

如果登录的用户没有ADMIN角色,尝试访问/user/list时,会收到权限不足的提示,无法访问该资源。

五、自定义异常处理

为了提升用户体验,我们可以自定义异常处理器,返回统一的JSON格式错误信息。

1. 自定义未授权处理器

public class MyAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response,
                       AccessDeniedException accessDeniedException) throws IOException, ServletException {
        // 创建结果对象
        HashMap<String, Object> result = new HashMap<>();
        result.put("code", -1);
        result.put("message", "没有访问该资源的权限");
        // 转换成JSON字符串
        String json = JSON.toJSONString(result);
        // 返回响应
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().println(json);
    }
}

2. 注册自定义异常处理器

http.exceptionHandling(exception -> {
    // 请求未认证的处理
    exception.authenticationEntryPoint(new MyAuthenticationEntryPoint());
    // 请求未授权的处理
    exception.accessDeniedHandler(new MyAccessDeniedHandler());
});

通过上述配置,当用户没有权限访问某个资源时,会返回自定义的JSON错误信息,方便前端进行处理。

六、总结

通过以上步骤,我们实现了基于用户-角色-资源的权限控制:

  • 用户:通过UserDetailsService加载用户信息,并为其分配ADMIN角色。
  • 角色:使用.roles("ADMIN")方法为用户指定角色。
  • 资源:通过requestMatchers("/user/**").hasRole("ADMIN")指定需要ADMIN角色才能访问的资源。

这种方式的优势在于:

  • 管理方便:角色可以包含多个权限,简化了权限管理的复杂度。
  • 灵活性高:可以根据需要动态调整用户的角色,进而控制其访问权限。

在实际项目中,通常会有一个角色和权限的对应关系表,角色下包含多个权限,用户可以被分配一个或多个角色。

到此这篇关于使用Spring Security实现用户-角色-资源的权限控制的文章就介绍到这了,更多相关Spring Security角色权限控制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot DBUnit 单元测试(小结)

    SpringBoot DBUnit 单元测试(小结)

    这篇文章主要介绍了SpringBoot DBUnit 单元测试(小结),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • SpringCloud超详细讲解负载均衡组件Ribbon源码

    SpringCloud超详细讲解负载均衡组件Ribbon源码

    在微服务中,对服务进行拆分之后,必然会带来微服务之间的通信需求,而每个微服务为了保证高可用性,又会去部署集群,那么面对一个集群微服务进行通信的时候,如何进行负载均衡也是必然需要考虑的问题
    2022-07-07
  • 使用java -jar修改SpringBoot中application.properties的配置项

    使用java -jar修改SpringBoot中application.properties的配置项

    这篇文章主要介绍了使用java -jar修改SpringBoot中application.properties的配置项问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • JavaCV实现人脸检测功能

    JavaCV实现人脸检测功能

    这篇文章主要为大家详细介绍了JavaCV实现人脸检测功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • java中int值直接赋值给char类型的方法详解

    java中int值直接赋值给char类型的方法详解

    这篇文章主要给大家介绍了关于java中int值直接赋值给char类型的相关资料,文中通过代码介绍的非常详细,对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-12-12
  • java锁synchronized面试常问总结

    java锁synchronized面试常问总结

    这篇文章主要介绍了java锁synchronized面试常问总结分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • 手把手教你写Maven的archetype项目脚手架

    手把手教你写Maven的archetype项目脚手架

    本文主要介绍了Maven的archetype项目脚手架,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • Spring的异常处理@ExceptionHandler注解解析

    Spring的异常处理@ExceptionHandler注解解析

    这篇文章主要介绍了Spring的异常处理@ExceptionHandler注解解析,当一个Controller中有方法加了@ExceptionHandler之后,这个Controller其他方法中没有捕获的异常就会以参数的形式传入加了@ExceptionHandler注解的那个方法中,需要的朋友可以参考下
    2023-12-12
  • Java(基于Struts2) 分页实现代码

    Java(基于Struts2) 分页实现代码

    这篇文章介绍了Java(基于Struts2) 分页实现代码,有需要的朋友可以参考一下
    2013-10-10
  • 深入理解springboot中配置文件application.properties

    深入理解springboot中配置文件application.properties

    本文主要介绍了springboot中配置文件application.properties,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10

最新评论