spring学习之springSecurity(四)

我爱海鲸 2022-11-08 00:50:51 暂无标签

简介web鉴权、基于角色或权限进行访问控制

链接上一篇文章:spring学习之springSecurity(三)

1、基于角色或权限进行访问控制

hasAuthority 方法

如果当前的主体具有指定的权限,则返回 true,否则返回 false

修改配置类

添加一个控制器

@GetMapping("/find")
@ResponseBody
public String find(){
return "find";
}

给用户登录主体赋予权限

测试:

http://localhost:8080/findAll 

访问 findAll 进入登录页面

如果权限不正确,那么就会引导到对应的未授权页面

hasAnyAuthority 方法 

如果当前的主体有任何提供的角色(给定的作为一个逗号分隔的字符串列表)的话,返回
true.

hasRole 方法

如果用户具备给定角色就允许访问,否则出现 403。
如果当前主体具有指定的角色,则返回 true。

底层源码: 

给用户添加角色:

修改配置文件:
注意配置文件中不需要添加”ROLE_“,因为上述的底层代码会自动添加与之进行匹配。

hasAnyRole

表示用户具备任何一个条件都可以访问。 

给用户添加角色:

修改配置文件:

基于数据库实现权限认证

添加实体类 

@Data
public class Menu {
private Long id;
private String name;
private String url;
private Long parentId;
private String permission;
}
@Data
public class Role {
private Long id;
private String name;
}

编写接口与实现类

UserInfoMapper

/**
 * @author: haijin
 * @Date: 2022/11/07 23:59
 */
public interface UserInfoMapper {
    /**
     * 根据用户 Id 查询用户角色
     * @param userId 用户id
     * @return ignore
     */
    List<Role> selectRoleByUserId(Long userId);
    /**
     * 根据用户 Id 查询菜单
     * @param userId 用户id
     * @return ignore
     */
    List<Menu> selectMenuByUserId(Long userId);

}

上述接口需要进行多表管理查询:
需要在 resource/mapper 目录下自定义 UserInfoMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xyz.haijin.dao.UserInfoMapper">
    <!--根据用户 Id 查询角色信息-->
    <select id="selectRoleByUserId" resultType="xyz.haijin.entity.Role">
    SELECT r.id,r.name
    FROM role r
    INNER JOIN role_user ru ON
    ru.rid=r.id where ru.uid=#{0}
    </select>
    <!--根据用户 Id 查询权限信息-->
    <select id="selectMenuByUserId" resultType="xyz.haijin.entity.Menu">
     SELECT m.id,m.name,m.url,m.parentid,m.permission
        FROM menu m
        INNER JOIN role_menu rm ON m.id=rm.mid
        INNER JOIN role r ON r.id=rm.rid
        INNER JOIN role_user ru ON r.id=ru.rid
        WHERE ru.uid=#{0}
    </select>
</mapper>

 在配置文件中添加映射 

在配置文件中 application.yml 添加 

mybatis-plus:
  mapper-locations: classpath:mapper/*.xml

修改访问配置类 

/**
 * @author: haijin
 * @Date: 2022/10/29 23:56
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyUserDetailsServiceImpl myUserDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置没有权限访问跳转自定义页面
        http.exceptionHandling().accessDeniedPage("/unauth.html");
        // 配置认证
        http.formLogin()
                // 配置哪个 url 为登录页面
                .loginPage("/login.html")
                // 设置哪个是登录的 url。
                .loginProcessingUrl("/user/login")
                //登录成功之后,跳转路径
                .defaultSuccessUrl("/success.html").permitAll()
                // 登录失败之后,跳转的页面
                .failureUrl("/unauth.html")
                .permitAll()
                .and()
                .authorizeRequests()
                // 登录跳过页面
                .antMatchers("/user/login")
                // 指定 URL 无需保护。
                .permitAll()
                .antMatchers("/findAll")
                // 是否有admin的权限
                .hasRole("管理员")
                .antMatchers("/find")
                // 是否有role的权限
                .hasAnyAuthority("menu:system")
                // 其他请求
                .anyRequest()
                .authenticated(); //需要认证
        // 关闭 csrf
        http.csrf().disable();

    }

    // 注入 PasswordEncoder 类到 spring 容器中
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

}

使用管理员与非管理员进行测试

自定义 403 页面

http.exceptionHandling().accessDeniedPage("/unauth");

添加对应控制器

@GetMapping("/unauth")
public String accessDenyPage(){
return "unauth";
}
unauth.html
<body>
<h1>对不起,您没有访问权限!</h1>
</body>

 

 

你好:我的2025