Spring Security【编写查询权限方法 、配置类设置访问控制 、自定义访问控制逻辑 、注解设置访问控制 】(三)-全面详解(学习总结---从入门到深化)

 

目录

Spring Security授权_编写查询权限方法 

Spring Security授权_配置类设置访问控制 

Spring Security授权_自定义访问控制逻辑 

Spring Security授权_注解设置访问控制 

Spring Security授权_在前端进行访问控制 

Spring Security授权_403处理方案 


 

Spring Security授权_编写查询权限方法 

 Spring Security【编写查询权限方法 、配置类设置访问控制 、自定义访问控制逻辑 、注解设置访问控制 】(三)-全面详解(学习总结---从入门到深化)_第1张图片

 在认证后进行授权需要根据用户id查询到用户的权限,写法如下:

1、编写用户、角色、权限实体类

// 不要命名为User,避免和Spring Security提供的User混淆
@Data
public class Users {
    private Integer uid;
    private String username;
    private String password;
    private String phone;
}
// 角色
@Data
public class Role {
    private String rid;
    private String roleName;
    private String roleDesc;
}
// 权限
@Data
public class Permission {
    private String pid;
    private String permissionName;
    private String url;
}

2、编写UserMapper接口

// 根据用户名查询权限
List findPermissionByUsername(String username);

3、在resources目录中编写UsersMapper的映射文件





4、测试方法

@SpringBootTest
public class UsersMapperTest {
    @Autowired
    private UsersMapper usersMapper;
    @Test
    public void testFindPermissionByUsername(){
        List baizhan = usersMapper.findPermissionByUsername("tong");
        baizhan.forEach(System.out::println);
   }
}

5、修改认证逻辑,认证成功后给用户授权

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

Spring Security授权_配置类设置访问控制 

Spring Security【编写查询权限方法 、配置类设置访问控制 、自定义访问控制逻辑 、注解设置访问控制 】(三)-全面详解(学习总结---从入门到深化)_第2张图片

 在给用户授权后,我们就可以给系统中的资源设置访问控制,即拥 有什么权限才能访问什么资源。

1、编写控制器类,添加控制器方法资源

@RestController
public class MyController {
    @GetMapping("/reportform/find")
    public String findReportForm() {
        return "查询报表";
   }
    @GetMapping("/salary/find")
    public String findSalary() {
        return "查询工资";
   }
    @GetMapping("/staff/find")
    public String findStaff() {
        return "查询员工";
   }
}

2、修改Security配置类

// 权限拦截配置
http.authorizeRequests()
       .antMatchers("/login.html").permitAll() //表示任何权限都可以访问
       .antMatchers("/reportform/find").hasAnyAuthority("/reportform/find") // 给资源配置需要的权限
       .antMatchers("/salary/find").hasAnyAuthority("/salary/find")
       .antMatchers("/staff/find").hasAnyAuthority("/staff/find")
       .anyRequest().authenticated();  //表示任何请求都需要认证后才能访问

3、测试访问资源,由于没有权限被拦截访问时会抛出403异常

Spring Security授权_自定义访问控制逻辑 

如果资源数量很多,一条条配置需要的权限效率较低。我们可以自 定义访问控制逻辑,即访问资源时判断用户是否具有名为该资源 URL的权限。

1、自定义访问控制逻辑

@Service
public class MyAuthorizationService {
    // 自定义访问控制逻辑,返回值为是否可以访问资源
    public boolean hasPermission(HttpServletRequest request,Authentication authentication){
        // 获取会话中的登录用户
        Object principal = authentication.getPrincipal();
        if (principal instanceof UserDetails){
            // 获取登录用户的权限
            Collection authorities = ((UserDetails)principal).getAuthorities();
            // 获取请求的URL路径
            String uri = request.getRequestURI();
            // 将URL路径封装为权限对象
            SimpleGrantedAuthority authority = new SimpleGrantedAuthority(uri);
            // 判断用户的权限集合是否包含请求的URL权限对象
            return authorities.contains(authority);
       }
        return false;
   }
}

2、在配置文件中使用自定义访问控制逻辑

// 权限拦截配置
http.authorizeRequests()
               .antMatchers("/login.html").permitAll() //表示任何权限都可以访问
                // 任何请求都使用自定义访问控制逻辑
               .anyRequest().access("@myAuthorizationService.hasPermission(request,authentication)"
);

Spring Security授权_注解设置访问控制 

 除了配置类,在SpringSecurity中提供了一些访问控制的注解。这 些注解默认都是不可用的,需要开启后使用。

@Secured

该注解是基于角色的权限控制,要求UserDetails中的权限名必须以 ROLE_ 开头。

1、在配置类开启注解使用

@SpringBootApplication
@MapperScan("com.tong.mysecurity.mapper")
@EnableGlobalMethodSecurity(securedEnabled=true)
public class MysecurityApplication {
    public static void main(String[] args)
   {
      SpringApplication.run(MysecurityApplication.class, args);
   }
}

2、在控制器方法上添加注解

@Secured("ROLE_reportform")
@GetMapping("/reportform/find")
public String findReportForm() {
    return "查询报表";
}

@PreAuthorize 

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

1、在配置类开启注解使用

@SpringBootApplication
@MapperScan("com.tong.mysecurity.mapper")
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MysecurityApplication {
    public static void main(String[] args)
    {
      SpringApplication.run(MysecurityApplication.class, args);
   }
}

2、在控制器方法上添加注解

@PreAuthorize("hasAnyAuthority('/reportform/find')")
@GetMapping("/reportform/find")
public String findReportForm() {
    return "查询报表";
}

Spring Security授权_在前端进行访问控制 

Spring Security【编写查询权限方法 、配置类设置访问控制 、自定义访问控制逻辑 、注解设置访问控制 】(三)-全面详解(学习总结---从入门到深化)_第3张图片

 SpringSecurity可以在一些视图技术中进行控制显示效果。例如 Thymeleaf中,只有登录用户拥有某些权限才会展示一些菜单。

1、在pom中引入Spring Security和Thymeleaf的整合依赖



    org.thymeleaf.extras
    thymeleaf-extras-springsecurity5

2、在Thymeleaf中使用Security标签,控制前端的显示内容




    
    主页面


主页面

退出登录

3、这样面对不同权限的用户,前端可以显示不同的菜单

Spring Security授权_403处理方案 

Spring Security【编写查询权限方法 、配置类设置访问控制 、自定义访问控制逻辑 、注解设置访问控制 】(三)-全面详解(学习总结---从入门到深化)_第4张图片

使用Spring Security时经常会看见403(无权限),这样的页面很 不友好,我们可以自定义403异常处理方案: 

1、编写权限不足页面 noPermission.html




    
    权限不足


  

您的权限不足,请联系管理员!

2、编写权限不足处理类

public class MyAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
      response.sendRedirect("/noPermission.html");
   }
}

3、在Spring Security配置文件中配置异常处理

//异常处理
http.exceptionHandling().
                accessDeniedHandler(new MyAccessDeniedHandler());

你可能感兴趣的:(Spring全家桶,#,Spring,Security,mybatis,Spring,Security)