SpringSecurity基本使用

2023-11-16

1.基本使用

1.pom依赖

 		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

2.编写Controller测试

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello World!";
    }
}

3.启动项目,访问 http://localhost:9999/hello

在这里插入图片描述

用户名为 user,密码在启动项目的控制台可以看到:

在这里插入图片描述

输入后显示文字:
在这里插入图片描述

2.自定义配置用户名与密码

方式一:在配置文件里配置

spring.security.user.name=admin
spring.security.user.password=123456
spring.security.user.roles=admin

方式二:配置类里配置

@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String password = passwordEncoder.encode("123456");
        auth.inMemoryAuthentication().withUser("admin").password(password).roles("admin");
    }

    @Bean
    PasswordEncoder password() {
        return new BCryptPasswordEncoder();
    }
}

方式三:动态地从数据库中查

1.建表

CREATE TABLE `db_user`(
  `id` int NOT NULL AUTO_INCREMENT,
  `username` varchar(20) NOT NULL,
  `password` varchar(255) NULL,
  PRIMARY KEY (`id`)
);

2.pom

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1.tmp</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>

3.配置数据源

spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/db_user?useSSL=false&serverTimezone=Asia/Shanghai

4.编写实体类

@Data
@TableName("tb_user")
public class LoginUser {
    private Integer id;
    private String username;
    private String password;
}

5.Mapper

@Mapper
public interface UserMapper extends BaseMapper<LoginUser> {
}

6.编写Service

@Service("userDetailsService")
public class UserDeatilsServiceImpl implements UserDetailsService {

    @Resource
    UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
       //1.构建查询条件,从数据库查询用户
        QueryWrapper<LoginUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",s);
        LoginUser loginUser = userMapper.selectOne(queryWrapper);
        //2.将用户信息转换为springsecurity中的User
        List<GrantedAuthority> authority = AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_admin,ROLE_sale");
        User user = new User(loginUser.getUsername(),
                new BCryptPasswordEncoder().encode(loginUser.getPassword()),
                authority);
        return user;
    }
}

7.将Service注册到SpringSecurity中

@Configuration
public class MyWebSecurityConfig02 extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService userDetailsService;

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

    @Bean
    PasswordEncoder password() {
        return new BCryptPasswordEncoder();
    }
}

3.自定义登录页面

@Configuration
public class MyWebSecurityConfig02 extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService userDetailsService;

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .loginPage("/login.html")
                .loginProcessingUrl("/user/login")
                .defaultSuccessUrl("/test/index").permitAll()
                .and().authorizeRequests()
                    .antMatchers("/","/test/hello","/user/login").permitAll()
                .and().authorizeRequests()
                    .anyRequest().authenticated()
                .and().csrf().disable();
    }

    @Bean
    PasswordEncoder password() {
        return new BCryptPasswordEncoder();
    }
}

/static/login.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"/>
    <title>登录</title>
</head>
<body>
<form action="/user/login" method="post">
    用户名:<input type="text" name="username"/><br/>
    密码:<input type="password" name="password"/><br/>
    <input type="submit" value="提交"/>
</form>
</body>
</html>

4.基于权限访问控制

SpringSecurity判断时是从UserDetailsService中获取用户,进而判断用户是否满足角色或者权限。

@Service("userDetailsService")
public class UserDeatilsServiceImpl implements UserDetailsService {

    @Resource
    UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        //1.构建查询条件,从数据库查询用户
        QueryWrapper<LoginUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",s);
        LoginUser loginUser = userMapper.selectOne(queryWrapper);
        //2.将用户信息转换为springsecurity中的User
        List<GrantedAuthority> authority = AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_admin,ROLE_sale");
        User user = new User(loginUser.getUsername(),
                new BCryptPasswordEncoder().encode(loginUser.getPassword()),
                authority);
        return user;
    }
}

1.在配置类里配置

   @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .loginPage("/login.html")
                .loginProcessingUrl("/user/login")
                .defaultSuccessUrl("/test/index").permitAll()
                .and().authorizeRequests()
                    .antMatchers("/","/user/login").permitAll()
                .and().authorizeRequests()
                    .antMatchers("/test/hello","/admin2")
                        .hasAnyRole("sale,admin")
                .and().authorizeRequests()
                    .anyRequest().authenticated()
                .and().csrf().disable();
    }

(1)hasAuthority方法:

.antMatchers("/admin","/admin2").hasAuthority("admin")

(2)hasAnyAuthority方法:满足其中一个就放行,多个权限用逗号隔开

.antMatchers("/admin","/admin2").hasAnyAuthority("admin,teacher")
.antMatchers("/admin","/admin2").hasAnyAuthority("admin","teacher")

(3)hasRole方法:

*注意:UserDetailsService中返回的用户里的角色是带ROLE_前缀的,但在配置里不需要写前缀。因为hasRole方法最终会帮我们加入前缀。

在这里插入图片描述

.hasRole("admin")

hasAnyRole:使用方法同hasAnyAuthority

.hasAnyRole("sale,admin")

5.自定义403

当权限验证没通过的时候就会报403,但是默认返回的页面我们不是很满意,就可以在配置类里自定义去进行更改。

	 @Override
    protected void configure(HttpSecurity http) throws Exception {
		http.exceptionHandling().accessDeniedPage("/unauth");
    }

其中/auth可以自己定义,可以写为一个url,这样403的时候就会跳转到对应url的Controller的方法里:

	@RequestMapping("/unauth")
    public String unauth() {
        return "权限不足,请联系管理员";
    }

也可以写网页的路径,如/403.html,然后在 resource/static文件夹下创建网页。

6.使用注解

@Secured、@PreAuthorize、@PostAuthorize

1.首先在启动类上开启

想启用哪个注解就开哪个:

在这里插入图片描述

@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityApplication {

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

}

2.在方法上标注解

  • @Secured 判断是否具有角色,另外需要注意的是这里匹配的字符串需要添加前缀“ROLE_“。

    @ResponseBody
    @Secured({"ROLE_normal","ROLE_admin"})
    public String helloUser() {
    	return "hello,user";
    }
    
  • @PreAuthorize:注解适合进入方法前的权限验证, @PreAuthorize 可以将登录用户的 roles/permissions 参数传到方法中。

    @RequestMapping("/preAuthorize")
    @ResponseBody
    //@PreAuthorize("hasRole('ROLE_管理员')")
    @PreAuthorize("hasAnyAuthority('menu:system')")
    public String preAuthorize(){
    	System.out.println("preAuthorize");
    	return "preAuthorize";
    }
    
    /**
     * 限制只能查询自己的信息
     */
    @PreAuthorize("principal.username.equals(#username)")
    public User find(String username) {
        return null;
    }
    

    权限表达式:https://docs.spring.io/spring-security/site/docs/5.3.4.RELEASE/reference/html5/#overview-2

  • @PostAuthorize @PostAuthorize 注解使用并不多,在方法执行后再进行权限验证,适合验证带有返回值的权限.

    @RequestMapping("/testPostAuthorize")
    @ResponseBody
    @PostAuthorize("hasAnyAuthority('menu:system')")
    public String preAuthorize(){
    	System.out.println("test--PostAuthorize");
    	return "PostAuthorize"; 
    }
    
@PostFilter、@PreFilter

@PostFilter : 权限验证之后对数据进行过滤 留下用户名是 admin1 的数据

表达式中的 filterObject 引用的是方法返回值 List 中的某一个元素

@RequestMapping("getAll")
@PreAuthorize("hasRole('ROLE_管理员')")
@PostFilter("filterObject.username == 'admin1'")
@ResponseBody
public List<UserInfo> getAllUser(){
 	ArrayList<UserInfo> list = new ArrayList<>();
    list.add(new UserInfo(1l,"admin1","6666"));
 	list.add(new UserInfo(2l,"admin2","888"));
	return list;
}

3.7.5 @PreFilter

@PreFilter: 进入控制器之前对数据进行过滤

@RequestMapping("getTestPreFilter")
@PreAuthorize("hasRole('ROLE_管理员')")
@PreFilter(value = "filterObject.id%2==0")
@ResponseBody
public List<UserInfo> getTestPreFilter(@RequestBody List<UserInfo> list){
    list.forEach(t-> {
        System.out.println(t.getId()+"\t"+t.getUsername());
    });
	return list;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringSecurity基本使用 的相关文章

随机推荐

  • Windows下的oracle 11g的入门

    图全部都挂了 写的太累了 有空再来更 几个月没用oracle之后 花了一个下午把oracle的基本操作迅速捡回来了 记录如下 一 安装oracle11G 1 1 首先要下载oracle服务端和客户端 官网下载链接如下 http www or
  • content-type的几种取值

    目录 Content Type的几种取值 1 text plain 2 text html 3 application json 4 application xml 5 image jpeg 6 image png 7 audio mpeg
  • Socket编程基础

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 基于TCP的socket通信流程 二 基于UDP的socket通信流程 三 TCP协议下socket编程主要API接口介绍 1 int socket in
  • 【Java】迭代器之:Iterable & Iterator

    在我们Java中的迭代器是一个接口 名为Iterator 他有两个抽象方法 hasNext方法 用来判断还有没有数据访问 next方法 用来访问集合的下一个数据 迭代器可以访问不同特性的集合数据 而无需关心他们的内部实现 注意 集合并不是直
  • 小学奥数题使用python解决(使用2倒9中不重复的数使得{}+{}={}{}-{}=1{}满足)

    使用2 9中不重复的数使得 1 满足 样子不太好看 1 利用for循环和if语句 代码 利用2 9不重复的数使得 1 i 0 for a1 in range 2 10 for a2 in range 2 10 if a1 a2 and a1
  • 新学期阅读计划

    1 再认真阅读 设计模式之禅 在理解的基础上应用设计模式 2 编程之美 共4章 61个有意思的题目 3 图书馆借阅 算法导论 4 再阅读 算法之道 5 了解 操作系统导论 真正理解不要死记硬背 6 反复多次阅读经典的论文 特别是及时和师姐多
  • 部署篇-Zabbix中文乱码字符集的修正

    部署zabbix监控后默认是英文 默认不支持中文字符集 切换成中文后会出现以下情况 解决方案 从Window服务器找到相应的字休复制到zabbix Server服务器上 控制面板 字体 选择一种中文字体 建议simkai ttf root
  • Java堆和栈应用实例

    以下是一个简单的Java程序 演示了Java堆和栈的应用实例 public class HeapAndStackExample public static void main String args 创建一个对象并分配在堆内存中 Perso
  • CTFshow web入门---web56

    CTFshow web入门 web56 题目 题目分析 查看本题 发现本题为命令执行类题目 但是有一个很致命的点 那么就是他过滤了所有的字母和数字 以及一系列的符号 因此本题最值得推敲的点就是如何实现无字母数字的命令执行 通过拜读P神的一篇
  • 关系型数据库RDBMS -MySQL基础入门(三)数据分片

    数据分片 相关概念 分库分表 分片 存在一台数据库的服务器中的数据 特定方式拆分 分散存放在多台数据库服务中 达到单台服务器负载的效果 垂直分割 纵向切分 按业务类型 什么是垂直分割 纵向切分 把单一的表 拆分成多个表 并分散到不同的数据库
  • 深入理解gtest C/C++单元测试经验谈

    Google C Testing Framework 简称gtest http code google com p googletest 是Google公司发布的一个开源C C 单元测试框架 已被应用于多个开源项目及Google内部项目中
  • spring Data JPA 拾遗

    Preface JPA在国内的使用频率较小 但也是一个值得学习的极为优秀的ORM框架 DDD的思想在里面体现得淋漓尽致 结构图 配置 1 2 3 4 5 6 7 8 9 10 11 spring jpa generate ddl false
  • 搭建jboss

    jboss 是中间件comcat是框架 jboss 基于java需要安装jbk配置环境变量 配置环境变量 我的电脑 右键 属性 高级 环境变量 新建系统变量 变量名为 JAVA HOME 变量值 C Program Files Java j
  • SpringBoot系统列 5 - 接口版本控制、SpringBoot FreeMarker模板引擎

    接着上篇博客的代码继续写 1 接口版本控制 一个系统上线后会不断迭代更新 需求也会不断变化 有可能接口的参数也会发生变化 如果在原有的参数上直接修改 可能会影响线上系统的正常运行 这时我们就需要设置不同的版本 这样即使参数发生变化 由于老版
  • 数据结构(Python版):线性表

    2 线性表 线性数据结构 线性结构是一种有序数据项的集合 其中每个数据项都有唯一的前驱和后继 除了第一个没有前驱 最后一个没有后继 新的数据项加入到数据集中时 只会加入到原有某个数据项之前或之后 具有这种性质的数据集 就称为线性结构 顺序表
  • 学习常用模型及算法:3.评价和预测

    评价方法 1 加权平均法 最简单的方法 但不能忽视 2 层次分析法 该题可划分为三层 首先我们要求得准则层对目标层的权重 我们可以引进判断矩阵的概念 以两两比较的方式判断每两个指标中哪个更为重要 因为这里是4个判断标准 所以n 4 RI n
  • 5G QoS控制原理专题详解(7)-Default QoS Flow探秘

    相关文章会在公众号同步更新 最近工作忙 更新完公众号后 经常容易忘记再CSDN上再发 公众号上的文章更新的能快一些 各位同学有兴趣可以关注一下 公众号 5G通信大家学 持续更新的相关5G内容都是直接根据3GPP整理 保证更新内容的准确性 避
  • 【MybatisPlus逆向工程】代码生成器

    使用mybatis plus的逆向工程生成entity controller service mapper的初始代码 参考链接 https baomidou com pages d357af E6 B7 BB E5 8A A0 E4 BE
  • linux:ubuntu 查看ip

    解决方法 ifconfig a 或者sudo vi etc netplan 00 installer config yaml 进行查看
  • SpringSecurity基本使用

    文章目录 1 基本使用 2 自定义配置用户名与密码 3 自定义登录页面 4 基于权限访问控制 5 自定义403 6 使用注解 Secured PreAuthorize PostAuthorize PostFilter PreFilter 1