本系统权限控制采用 RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联。简单地说,一个用户拥有若干角色,每一个角色拥有若干权限,每一个角色拥有若干个菜单,这样,就构造成“用户-角色-权限”,“角色-菜单” 的授权模型。在这种模型中,用户与角色、角色与权限、角色与菜单之间构成了多对多的关系,如下图系统权限 - 图1

后端权限控制

后端接口权限控制基于Spring Security(不清楚的可以自己去学习学习),因此每个请求都将携带token进行访问,当然可以过滤一些接口如:Druid监控,swagger文档,支付宝回调等。配置文件位于:core -> config -> WebSecurityConfig

  1. // 关键代码
  2. @Override
  3. protected void configure(HttpSecurity httpSecurity) throws Exception {
  4. httpSecurity
  5. // 禁用 CSRF
  6. .csrf().disable()
  7. // 授权异常
  8. .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
  9. // 不创建会话
  10. .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
  11. .authorizeRequests()
  12. .antMatchers("/auth/**").permitAll()
  13. .antMatchers("/websocket/**").permitAll()
  14. .antMatchers("/druid/**").anonymous()
  15. // 支付宝回调
  16. .antMatchers("/api/aliPay/return").anonymous()
  17. .antMatchers("/api/aliPay/notify").anonymous()
  18. // swagger start
  19. .antMatchers("/swagger-ui.html").anonymous()
  20. .antMatchers("/swagger-resources/**").anonymous()
  21. .antMatchers("/webjars/**").anonymous()
  22. .antMatchers("/*/api-docs").anonymous()
  23. // swagger end
  24. .antMatchers("/test/**").anonymous()
  25. .antMatchers(HttpMethod.OPTIONS, "/**").anonymous()
  26. // 所有请求都需要认证
  27. .anyRequest().authenticated();
  28. httpSecurity
  29. .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
  30. }
数据交互

用户输入账号密码 -> 验证账号密码返回token -> 前端带上token请求数据 -> 后端返回数据数据交互流程如下图:系统权限 - 图2

接口权限控制

Spring Security允许我们在定义URL访问或方法访问所应有的权限时使用Spring EL表达式。如下表示用户拥有 ADMINMENU_ALLMENU_EDIT 三个权限中的任意一个就能能访问update方法,但是如果方法前不加@preAuthorize注解,意味着所有用户都能访问update

  1. @Log(description = "修改菜单")
  2. @PutMapping(value = "/menus")
  3. @PreAuthorize("hasAnyRole('ADMIN','MENU_ALL','MENU_EDIT')")
  4. public ResponseEntity update(@Validated @RequestBody Menu resources){
  5. // 略
  6. }

前端权限控制

前端页面的权限控制只需要引入权限判断函数,使用如下 v-if 去验证,用户没有该权限就不会显示该标签与该标签内的内容,具体代码如下:

  1. <template>
  2. <el-tab-pane v-if="checkPermission(['ADMIN'])" label="Admin">
  3. admin 权限的用户才能看到
  4. </el-tab-pane>
  5. </template>
  6. <script>
  7. import checkPermission from '@/utils/permission' // 权限判断函数
  8. export default{
  9. methods: {
  10. checkPermission
  11. }
  12. }
  13. </script>