SpringBoot 1x 系列之(十二)Spring Boot与安全

Spring Boot与安全

安全、Spring Security

安全:身份认证、权限控制、漏洞攻击

安全框架:

1)shiro

2)Spring Security

Spring Boot底层是使用Spring Security作为安全框架

安全框架最主要的两个功能:认证、授权

认证:根据认证信息(用户名、密码等)证明你是这个人,指建立用户的过程

授权:能干什么

1. 使用Spring Security

1)引入依赖

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

2)编写Spring Security的配置类

配置类需要继承WebSecurityConfigurerAdapter 并且标注@EnableWebSecurity (开启Web安全模式)

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}

3)控制请求的访问权限

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
  	// 参数为HttpSecurity的configure的方法用于定制授权规则
  	// 参数为AuthenticationManagerBuilder的configure的方法用于定制认证规则
  
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        父类会有一些定制规则,我们要完全自己定义,所以要注释掉
//        super.configure(http);

//        定制请求的授权规则(Authorization):实际上就是建立请求路径与角色之间的映射关系
//        permitAll():允许任何人访问
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("VIP1")
                .antMatchers("/level2/**").hasRole("VIP2")
                .antMatchers("/level3/**").hasRole("VIP3");
//      开启自动配置的登录功能
//        1、/login来到登录页
//        2、认证失败重定向到/login?error
        http.formLogin();
      
        //开启自动配置的注销功能。
        //1、访问/logout 表示用户注销并清空session
        //2、注销成功默认会返回/login?logout页面;
        //.logoutSuccessUrl("/"):定制注销成功后的请求,注销成功以后来到首页
        http.logout().logoutSuccessUrl("/");
    }

//    定制认证规则(Authentication):实际上就是向SpringSecurity中增加管理的携带角色的用户
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        super.configure(auth);
        auth.inMemoryAuthentication()
                .withUser("zhangsan").password("111").roles("VIP1").and()
                .withUser("lisi").password("222").roles("VIP1","VIP2").and()
                .withUser("wangwu").password("333").roles("VIP1","VIP2","VIP3");
    }
}

注销表单的方法必须是post

<form th:action="@{/logout}" method="post">
   <input type="submit" value="注销">
</form>

2. Thymeleaf对Spring Security的支持

需求描述:实现权限控制功能,网页内容按照不同角色显示不同内容

引入thymeleaf和springsecurity整合包依赖并指定版本

<!-- 由于thymeleaf-extras-springsecurity4做了版本仲裁,修改版本设置属性就可以了 -->
<properties>
  <thymeleaf-extras-springsecurity4.version>3.0.2.RELEASE</thymeleaf-extras-springsecurity4.version>
</properties>

<dependencies>
  <dependency>
      <groupId>org.thymeleaf.extras</groupId>
      <artifactId>thymeleaf-extras-springsecurity4</artifactId>
  </dependency>
</dependencies>
<!DOCTYPE html>
<!--xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4" 名称空间-->
<html xmlns:th="http://www.thymeleaf.org"
     xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1 align="center">欢迎光临武林秘籍管理系统</h1>
<!--未认证才显示:isAuthenticated() 返回认证结果-->
<div sec:authorize="!isAuthenticated()">
   <h2 align="center">游客您好,如果想查看武林秘籍 <a th:href="@{/login}">请登录</a></h2>
</div>
<!--认证过才显示-->
<div sec:authorize="isAuthenticated()">
<!--   sec:authentication="name":取出认证过的用户名    -->
<!--   sec:authentication="principal.authorities":获取当前用户的所以角色-->
   <h2><span sec:authentication="name"></span>您好,您的角色有:<span sec:authentication="principal.authorities"></span></h2>
   <form th:action="@{/logout}" method="post">
      <input type="submit" value="注销">
   </form>
</div>

<hr>
<!--如果当前用户有VIP1角色才显示下面的内容-->
<div sec:authorize="hasRole('VIP1')">
   <h3>普通武功秘籍</h3>
   <ul>
      <li><a th:href="@{/level1/1}">罗汉拳</a></li>
      <li><a th:href="@{/level1/2}">武当长拳</a></li>
      <li><a th:href="@{/level1/3}">全真剑法</a></li>
   </ul>
</div>
<!--如果当前用户有VIP2角色才显示下面的内容-->
<div sec:authorize="hasRole('VIP2')">
   <h3>高级武功秘籍</h3>
   <ul>
      <li><a th:href="@{/level2/1}">太极拳</a></li>
      <li><a th:href="@{/level2/2}">七伤拳</a></li>
      <li><a th:href="@{/level2/3}">梯云纵</a></li>
   </ul>
</div>
<!--如果当前用户有VIP3角色才显示下面的内容-->
<div sec:authorize="hasRole('VIP3')">
   <h3>绝世武功秘籍</h3>
   <ul>
      <li><a th:href="@{/level3/1}">葵花宝典</a></li>
      <li><a th:href="@{/level3/2}">龟派气功</a></li>
      <li><a th:href="@{/level3/3}">独孤九剑</a></li>
   </ul>
</div>
</body>
</html>

3. 记住我

登录后,下次访问系统不用再登录

在Spring Security的配置类中开启即可

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
      		 //开启记住我功能
      		 //登录成功以后,SpringSecurity将Cookie发给浏览器保存,以后访问页面带上这个Cookie,只要通过SpringSecurity的检查就可以免登录
      		 //点击注销会删除Cookie
              http.rememberMe();
    }
}

开启后,登录页面默认会出现是否记住我的选项

勾选后,Cookie默认14天内有效,14天以后Cookie自动删除

点击注销发起的请求会删除Cookie

4. 定制登录页

Spring Security提供了默认的登录页,如何替换成我们自定义的登录页呢?

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
      		 //.formLogin():开启自动配置的登录功能,开启后默认将/login作为登录页
      		 //.usernameParameter("username"):指定表单提交用户名输入框的name属性值
      		 //.passwordParameter("password"):指定表单提交密码输入框的name属性值
      		 //.loginPage("/userlogin"):自定义登录页为/userlogin
      		 //		loginPage指定后,/userlogin get作为登录页
      		 //					   /userlogin post作为处理登录的请求
              http.formLogin()
                .usernameParameter("username")
                .passwordParameter("password")
                .loginPage("/userlogin");
    }
}

替换登录页后,需要我们自己指定表单提交到哪个请求,提交的数据中用户名和密码的name是怎么指定的

表单提交到哪个请求:

​ 当我们通过.loginPage("/xxx")自定义登录页后,POST方法提交到/xxx的请求就是处理登录的。

表单的用户名和密码的name:

​ 默认是username和password,意思是我们自己的表单要把用户名和密码的输入框name属性设为username和password。

为自定义的登录页添加记住我

name属性的值是在配置类中配置的

http.rememberMe().rememberMeParameter("me");
posted @   刘二水  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示