SpringBoot 03 —— Spring Security

Series of articles

SpringBoot 01-HelloSpringBoot, yaml configuration, data verification, multi-environment switching
SpringBoot 02-Simple Web exploration, employee management system
SpringBoot 03-Spring Security
SpringBoot 04-Shiro



Eleven, Spring Security

 
Introduction

Spring Security is a powerful and highly customizable framework for authentication and access control. It is a standard for protecting Spring-based applications.

Spring Security is to solve the security problem of Web development, just like the filters and interceptors we wrote before, and Spring Security is equivalent to a framework of filters, which can help us omit a lot of code.

For example, we used interceptors or filters to control access before, requiring users to log in to enter the main page, or the pages entered by users with different permissions are not the same, but the code written before is more complicated and redundant, and use The framework can be easily implemented.

 
There are a few key categories to remember :

  • WebSecurityConfigurerAdapter: custom security policy
  • AuthenticationManagerBuilder: custom authentication strategy
  • @EnableWebSecurity: Turn on the WebSecurity function (seeing @EnableXXX is to turn on a certain function)

The two main goals of Spring Security are "authentication" and "authorization" (that is, access control). Shiro learned later is the same.

Official document: https://spring.io/guides/gs/securing-web/

 

Let's build a regular SpringBoot Web project.
 

11.1 Construction of experimental environment

1. Create a SpringBoot project, add a Web module, and import the Thymeleaf package.

<!--thymeleaf—— 命名空间xmlns:th="http://www.thymeleaf.org“ -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

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

 

2. Import the static resource file (you can find it from the Internet, you don’t need this step, just to make the interface look better, the current operation does not involve security)

Resource download link

Link: https://pan.baidu.com/s/1UoUJg6CsHm5bQbouYt609A Extraction code: nv8p

CSDN:https://download.csdn.net/download/qq_39763246/15982736

Need to turn off the cache of Thymeleaf

Insert picture description here

3. Write a routing and forwarding Controller to forward each page.

package com.zcy.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
//用户路由转发的Controller
public class RouterController {
    
    
  	//输入 localhost:8080或者localhost:8080/index都会跳转到首页
    @RequestMapping({
    
    "/index", "/"})
    public String index(){
    
    
        return "index";
    }
		
    @RequestMapping("/toLogin")
    public String toLogin(){
    
    
        return "views/login";
    }

    //通过Restful风格,在URL输入 level1/1就会跳转到1.html,输入level2/2就跳转到2.html
    @RequestMapping("/level1/{id}")
    public String level1(@PathVariable("id") int id){
    
    
        return "views/level1/"+id;
    }
    @RequestMapping("/level2/{id}")
    public String level2(@PathVariable("id") int id){
    
    
        return "views/level2/"+id;
    }
    @RequestMapping("/level3/{id}")
    public String level3(@PathVariable("id") int id){
    
    
        return "views/level3/"+id;
    }
}

4. Effect

image-20210320153106474 image-20210320153035563

 

11.2 Authentication and authorization

Create a new SecurityConfig.java

package com.zcy.config;

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

//这里用到了AOP,横切的思想,不会去改变我们Controller的代码。类似于拦截器,但更强大!
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    

    //授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        //链式编程

        //实现的功能:首页index 所有人都能访问,具体的功能也level 只能被有相应权限的人访问

        //给请求添加规则,使的访问level1下的所有请求都要有vip1权限
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");

        //如果没有权限,默认跳转至登录页面。这是Spring Security里内置的
        http.formLogin();

    }
    //认证(Spring Security 5.0+ 要求对密码加密才能正常使用)
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    
    
        //从内存中读取用户(提前设定好的用户,真实开发还是从数据库中读取,后面Shiro再讲)
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("zcy1").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1")
                .and()
                .withUser("zcy2").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1", "vip2")
                .and()
                .withUser("zcy3").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1", "vip2", "vip3");

        //从数据库读用户
    }
}

effect:

1. When you visit each page when you are not logged in, you will be redirected to the login page. It can be found that the request in the URL bar is /login, but we did not write this page, our login is views/login. This page is http.formLogin();provided in Spring Security .

image-20210320192355933

http.formLogin();Annotation of the source code:

Insert picture description here

Insert picture description here

2. The login user zcy1 has only the privileges of vip1 and can only access the pages under level1, and access to other pages will be blocked.

image-20210320191455802 image-20210320191525003

3. Login user zcy3, who owns vip1, vip2, vip3, can access all pages.
20210320191702817

 

11.3, logout and permission control

Effect picture:

  1. When not logged in

Insert picture description here

  1. Log in to zcy1 (note that we do not have a customized login page at this time, we use the built-in security, so clicking the login button is invalid, only URL input /login)

Insert picture description here

image-20210320210314315
  1. Log out of zcy1 and return to the homepage

  2. Login to zcy2

Insert picture description here

image-20210320210524201

 

Implementation:

1. Add logout in index.html

 <!--登录注销-->
<div class="right menu">
  <!--未登录-->
  <a class="item" th:href="@{/toLogin}">
    <i class="address card icon"></i> 登录
  </a>
  
  <!-- 注销 -->
  <a class="item" th:href="@{/logout}">
    <i class="sign-out card icon"></i> 注销
  </a>
</div>

2. Add logout in SecurityConfig.java

//授权
@Override
protected void configure(HttpSecurity http) throws Exception {
    
    
  //链式编程

  //实现的功能:首页index 所有人都能访问,具体的功能也level 只能被有相应权限的人访问

  //给请求添加规则,使的访问level1下的所有请求都要有vip1权限
  http.authorizeRequests()
    .antMatchers("/").permitAll()
    .antMatchers("/views/level1/**").hasRole("vip1")
    .antMatchers("/views/level2/**").hasRole("vip2")
    .antMatchers("/views/level3/**").hasRole("vip3");

  //如果没有权限,默认跳转至一个内置登录页面/login。这是Spring Security里内置的。
  http.formLogin(); //.loginPage("可以在这里指定自己的登录页面);
  
 	//关闭网站防攻击,默认会开启,因为我们前端用的<a>,是用get方式提交,不安全。
 	http.csrf().disable();//如果没有这句,注销会404
  
  //开启注销功能,logoutSuccessUrl作用是注销成功跳转到新url,点击注销跳转到首页
  http.logout().logoutSuccessUrl("/");
}

http.logout()Source code comments:

Insert picture description here
Insert picture description here

3. Thymeleaf integrates Spring Security

Our original customized homepage used the back end to pass the value to the front end, the front end judged, and then displayed, for example

<div th:if="${session.user.name}">
  ...显示专属内容
</div>

Now we directly integrate Spring Security in Thymeleaf

  • Pilot package
<!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity4 -->
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity4</artifactId>
    <version>3.0.4.RELEASE</version>
</dependency>
  • Reduce the Spring Boot version to 2.0.7 (Thymeleaf does not support higher versions to integrate Security, and now generally does not integrate Security)

    After lowering, the new version will be downloaded, version 2.0.7, we also need to change the junit package, see the picture below for details.

    image-20210320204444403
image-20210320204300382 image-20210320204315802
  • Modify index.html

    image-20210320210124100
image-20210320214127319

 

11.4, remember me and customized login page

1. Remember me: do not log out, you will automatically log in when you re-enter the page

Add code to the configure method of SecurityConfig.java:

//记住我,原理:添加Cookie到浏览器,关闭浏览器重新进入页面后保持登录状态
http.rememberMe();//默认保存两周

effect:
Insert picture description here

image-20210320211248172

2. Customize the login page

Modify the configure method of SecurityConfig.java:

//如果没有权限,默认跳转至一个内置登录页面/login。这是Spring Security里内置的。
//usernameParameter和passwordParameter指定前端传递过来的参数名称
//loginPage指定自己的登录页面
http.formLogin()
  .loginPage("/toLogin")
  .usernameParameter("user")
  .passwordParameter("pwd");
//.loginProcessingUrl("/login")可指定真正的URL,即在浏览器输入/toLogin,但请求是/login

//记住我,原理:添加Cookie到浏览器,关闭浏览器重新进入页面后保持登录状态
//默认保存两周.rememberMeParameter指定前端传递的参数名称
http.rememberMe()
  .rememberMeParameter("remember");

Modify index.html, the original parameter names are username and password, now they are modified. And add a radio button, remember me.

image-20210320212934320

Effect: Click the login button on the homepage to log in normally, and it has the remember me function.

Guess you like

Origin blog.csdn.net/qq_39763246/article/details/115035385