SpringSecurity集合(权限)

1、SpringSecurity授权

授权即认证通过后,系统给用户赋予一定的权限,用户只能根据权限访问系统中的某些资源。RBAC是业界普遍采用的授权方式,它有两种解释:

Role-Based Access Control

基于角色的访问控制,即按角色进行授权。比如在企业管理系统中,主体角色为总经理可以查询企业运营报表

Resource-Based Access Control

基于资源的访问控制,即按资源(或权限)进行授权。比如在企业管理系统中,用户必须 具有查询报表权限才可以查询企业运营报表

2、权限表设计

 用户角色,角色权限都是多对多关系,即一个用户拥有多个角色,一个角色属于多个用户;一个角色拥有多个权限,一个权限属于多个角色。这种方式需要指定用户有哪些角色,而角色又有哪些权限。

 3、自定义查询权限

@Service
public class MySecurityService implements UserDetailsService {
    @Autowired
    @Qualifier(value = "userMapper")
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//       1、查询条件
        QueryWrapper<Users> wrapper = new QueryWrapper<Users>().eq("username", username);
//      2、查询用户
        Users users = userMapper.selectOne(wrapper);
        if(users==null){
            return null;
        }
//      3.查询用户所有权限
        List<Permission> permissions = userMapper.findPermissionByUsername(username);
//      4.将自定义的权限集合转为Security的权限类型集合
        List<GrantedAuthority> list = new ArrayList<>();
        for (Permission permission:permissions) {
            list.add(new SimpleGrantedAuthority(permission.getUrl()));
        }
//      3、封装UserDetails对象
        UserDetails userDetails = User.withUsername(users.getUsername()).password(users.getPassword()).authorities(list).build();
        return userDetails;
    }
}

 3.1自定义访问权限

根据请求的路径进行拦截,如果user没有访问url的权限则状态码为403

//      需要认证的资源
        http.authorizeHttpRequests()
                .antMatchers("/login.html").permitAll()//登录页不需要认证
                .antMatchers("/fail").permitAll()//失败页面不需要认证
                //需要认证的权限
                .antMatchers("/reportform/find").hasAuthority("/reportform/find")
                .antMatchers("/salary/find").hasAuthority("/salary/find")
                .antMatchers("/tax/find").hasAuthority("/tax/find")
                .anyRequest().authenticated();//其余所有请求都需要认证

 @Secured

 通过@Secured注解添加访问权限(权限必须以ROLE_开头)不常用

@SpringBootApplication
@MapperScan
@EnableGlobalMethodSecurity(securedEnabled = true)//开启secured注解扫描
public class SpringSecurity2Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringSecurity2Application.class, args);
    }

}
//  对权限进行拦截必须以ROLE_开头,数据也必须以ROLE_开头
    @Secured("ROLE_/reportform/find")
    @GetMapping("/reportform/find")
    @ResponseBody
    public String testUrl1(){
        System.out.println("/reportform/find");
        return "/reportform/find权限拦截";
    }

    @Secured("/salary/find")//403没有权限
    @GetMapping("/salary/find")
    @ResponseBody
    public String testUrl2(){
        System.out.println("/salary/find");
        return "/salary/find权限拦截";
    }

    @Secured("/tax/find")//403没有权限
    @GetMapping("/tax/find")
    @ResponseBody
    public String testUrl3(){
        System.out.println("/tax/find");
        return "/tax/find权限拦截";
    }

@PreAuthorize(推荐)

该注解可以在方法执行前判断用户是否具有权限

//        默认放行首页和失败页    
    http.authorizeHttpRequests()
                .antMatchers("/login.html").permitAll()//登录页不需要认证
                .antMatchers("/fail").permitAll()//失败页面不需要认证
                //需要认证的权限
//                .antMatchers("/reportform/find").hasAuthority("/reportform/find")
//                .antMatchers("/salary/find").hasAuthority("/salary/find")
//                .antMatchers("/tax/find").hasAuthority("/tax/find")
                .anyRequest().authenticated();//其余所有请求都需要认证
@SpringBootApplication
@MapperScan
@EnableGlobalMethodSecurity(prePostEnabled = true) //开启@PreAuthorize注解扫描
public class SpringSecurity2Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringSecurity2Application.class, args);
    }

}
//url权限匹配    
@PreAuthorize("hasAnyAuthority('/salary/find')")
    @GetMapping("/salary/find")
    @ResponseBody
    public String testUrl2(){
        System.out.println("/salary/find");
        return "/salary/find权限拦截";
    }

    @PreAuthorize("hasAnyAuthority('/tax/find')")
    @GetMapping("/tax/find")
    @ResponseBody
    public String testUrl3(){
        System.out.println("/tax/find");
        return "/tax/find权限拦截";
    }

 前端控制访问权限

添加xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5",sec:authorize="hasAnyAuthority('/url')”若user有访问该url权限则显示此菜单

        <!--前端控制访问权限依赖-->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
    <meta charset="UTF-8">
    <title>主页面</title>
</head>
<body>
<span>主页面</span>
<span sec:authorize="hasAnyAuthority('/tax/find')"><a href="/tax/find">菜单一</a></span>
<span sec:authorize="hasAnyAuthority('/reportform/find')"><a href="/reportform/find">菜单二</a></span>
<span sec:authorize="hasAnyAuthority('/salary/find')"><a href="/salary/find">菜单三</a></span>
<a href="/logout">退出登录</a>
</body>
</html>

 SpringSecurity自定义权限不足页面,解决403权限异常

//自定义权限不足页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>权限异常</title>
</head>
<body>
  <span>权限不足</span>
</body>
</html>

 定义权限不足处理器类需要实现AccessDeniedHandler接口实现其中的handle方法

public class NoPermissionHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        System.out.println("权限不足");
        response.sendRedirect("/noPermission.html");
    }
}

 SecurityConfig权限配置类中添加自定义的权限不足处理器


//      权限不足异常
        http.exceptionHandling()
                .accessDeniedHandler(new NoPermissionHandler());

  博客:孤独&烙印的博客_CSDN博客-springSecurity,spring-fox,vue领域博主

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
采用SpringSecurity框架,用户登录采用拦截器实现,WebSecurityConfig实现WebSecurityConfigurerAdapter接口对拦截信息进行配置,包含设置登录页和允许访问的接口,自定义登录失败、登录成功返回对象,配置自定义密码验证拦截器对用户名和密码进行校验,判断是否为空,LoginValidateAuthenticationProvider实现AuthenticationProvider接口,获取用户名和密码,调用userService中loadUserByUsername方法,查询用户是否存在,校验用户密码是否正确,并查出用户对应的角色信息,并返回SecurityUser对象,用户身份已认证。项目启动时,执行定时任务,缓存权限数据,将需要通过认证的菜单及对应的角色信息和不需要认证的菜单分别存入reids,,用户登录后访问后台接口,拦截器调用getAttributes方法,获取redis中缓存的所有需要权限认证的url和不需要权限认证的url,获取当前访问的url信息,判断是当前访问的url是否需要认证,若为公共权限,不需要认证,直接返回null,若不是,返回该url对应的角色信息。返回后鉴权决策管理器AccessDecisionManagerImpl(实现AccessDecisionManager接口)中调用decide方法,判断configAttributes(该集合存角色信息)集合如果为空,直接通过,如果不为空,判断缓存中该url对应的角色列表是否包含当前用户角色信息,不包含抛出异常,包含则该url通过。项目中包含sql文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孤独&烙印

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值