Springboot 第九篇 集成SpringSecurity入门(安全)

本章只是一个小入门 SpringSecurity的功能是否强大,用户、角色、权限,还有注解配置控制器可以参考下一章,或者官方文档。

目录

1、创建工程

Springboot 第九篇 集成SpringSecurity入门(安全)
或者

<!--security安全-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<!--thymeleaf模板引擎-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--web-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2、简介

Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入 spring-boot-starter-security 模块,进行少量的配置,即可实现强大的安全管理!

记住几个类:

  • WebSecurityConfigurerAdapter:自定义Security策略
  • AuthenticationManagerBuilder:自定义认证策略
  • @EnableWebSecurity:开启WebSecurity模式

3、WebSecurityConfigurerAdapter

3.1 创建配置类

@EnableWebSecurity//开启Security
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //授权规则
    @Override
    protected void configure(HttpSecurity http) throws Exception {
      
    }

    //认证规则
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

}

3.2、授权规则

http.authorizeRequests().antMatchers("/").permitAll()
  .antMatchers("/level1/**").hasRole("vip1")
  .antMatchers("/level2/**").hasRoles("vip2","vip3")
  .antMatchers("/level3/**").hasRole("vip3");

测试发现在没有登录的情况下只能进入首页,其他页面必须登录并且有相对应的角色才能访问

3.3、开启登录、注销、记住我

//没有权限默认跳转到登录页,需要开启登录到页面
http.formLogin();
//关闭csrf功能
http.csrf().disable();
//注销,开启注销功能,跳转首页
http.logout().logoutSuccessUrl("/");
//开启记住我功能
http.rememberMe();

Springboot 第九篇 集成SpringSecurity入门(安全)点击记住我登录功能可以发现多了一条cookir用来记录到期时间
Springboot 第九篇 集成SpringSecurity入门(安全)

3.4、添加自定义登录页面

<input type="checkbox" name="remember"> 记住我

//自定义表单的name属性同名
http.rememberMe().rememberMeParameter("remember");
//自定义login页 默认登录请求页和登录页是应该页面 当然你可以如果loginProcessingUrl自定义
http.formLogin().loginPage("/toLogin")
//以下三个参数可以选择性使用
.loginProcessingUrl("login")//自定义登录请求
//自定义用户账号表单名 如果前端账号密码表单不是username 和password
.usernameParameter("reusername")
.passwordParameter("repassword");

Springboot 第九篇 集成SpringSecurity入门(安全)

4、AuthenticationManagerBuilder

4.1、添加认证规则

  1. 使用内存
   @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        在内存中定义,也可以在jdbc中去拿....
   //Spring security 5.0中新增了多种加密方式,也改变了密码的格式。
   //要想我们的项目还能够正常登陆,需要修改一下configure中的代码。我们要将前端传过来的密码进行某种方式加密
   //spring security 官方推荐的是使用bcrypt加密方式。
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("leitoqing").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2", "vip3")
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1", "vip3")
                .and()
                .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
    }
  1. 使用jdbc
 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication().dataSource(dataSource)
                .usersByUsernameQuery("select username,password, enabled from users where username = ?")
                .authoritiesByUsernameQuery("select username, role from user_roles where username = ?");
    }

5、前端

5.1、导入命名空间

xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"

5.2、修改导航栏,增加认证判断

  • sec:authorize 是否显示
  • isAuthenticated() 判断是否登录
<!--登录注销-->
<div class="right menu">

   <!--如果未登录-->
   <div sec:authorize="!isAuthenticated()">
       <a class="item" th:href="@{/login}">
           <i class="address card icon"></i> 登录
       </a>
   </div>

   <!--如果已登录-->
   <div sec:authorize="isAuthenticated()">
       <a class="item">
           <i class="address card icon"></i>
          用户名:<span sec:authentication="principal.username"></span>
          角色:<span sec:authentication="principal.authorities"></span>
       </a>
   </div>

   <div sec:authorize="isAuthenticated()">
       <a class="item" th:href="@{/logout}">
           <i class="address card icon"></i> 注销
       </a>
   </div>
</div>

5.3、角色判断

<!-- sec:authorize="hasRole('vip1')" -->
<div class="column" sec:authorize="hasRole('vip1')">
 ...
</div>

<div class="column" sec:authorize="hasRole('vip2')">
...
</div>

<div class="column" sec:authorize="hasRole('vip3')">
	...
</div>

5.4、登录看看

发现2显示不了因为没有这个角色
Springboot 第九篇 集成SpringSecurity入门(安全)

7、完整性代码

@EnableWebSecurity//开启Security
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    //授权规则
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //首页所有人都可以访问,功能页只有对应有权限都人才能访问
        http.authorizeRequests()
                .antMatchers("/").permitAll()//首页放行
                .antMatchers("/level1/**").hasAnyRole("vip1", "vip2")///level1/开头需要什么角色
                .antMatchers("/level2/**").hasRole("vip2");


        //没有权限默认跳转到登录页,需要开启登录到页面
        http.formLogin();
        //关闭csrf功能
        http.csrf().disable();
        //注销,开启注销功能,跳转首页
        http.logout().logoutSuccessUrl("/");
        //开启记住我功能
        http.rememberMe();
        // 自定义login页 默认登录请求页和登录页是应该页面 当然你可以如果loginProcessingUrl自定义
        http.formLogin().loginPage("/toLogin")
                .loginProcessingUrl("login")//自定义登录请求
        .usernameParameter("reusername")//自定义用户账号表单名 如果前端账号密码表单不是username 和password
        .passwordParameter("repassword");
        http.rememberMe().rememberMeParameter("remember");
    }

    //认证规则
    // 密码编码 passwordEncoder
    //在spring Secutiry5.0+ 增加类很多加密方法~
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //这是数据正常应该从数据库中读
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("leitoqing").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2", "vip3")
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1", "vip3")
                .and()
                .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
    }

}

上一篇:题解 洛谷 P1580 【yyy loves Easter_Egg I】


下一篇:Where do I get Trusted EC-Council 312-50 Questions for CEHv10 Exam?