Spring Security developed by Spring Boot (continued)

Spring Security developed by Spring Boot


Today, I will continue to learn the relevant knowledge and implementation of Spring Sercurity, which are very basic. First, open the last project and database. Last time we learned about certification, we will continue to learn today.

1. Authorization

1. Open the last project and database

insert image description here
insert image description here

2. Some pages can be accessed without logging in, such as homepage, login and registration, etc. Therefore, for some requests that do not require login, these interfaces are allowed

(1) Modify MySercurityConfig

insert image description here

    //  授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        http.authorizeHttpRequests()//拦截所有请求
                .antMatchers("/home", "/test", "/login").permitAll()//某些请求不需要登录->放行某些接口
                .anyRequest().authenticated();//其他的接口拦截
        http.formLogin();//拦截后跳转到表单页面
    }

(2) Modify the TestController class

insert image description here

    @RequestMapping("home")
    public String home(){
    
    
        return "test.html";
    }

(3) Click Run, you don’t need to log in to access /home and /login paths when you are not logged in, and other interfaces are intercepted and jump to the login page

insert image description here

insert image description here
insert image description here

3. Modify the MySercurityConfig class and add an admin user. The user user has user permissions, and the admin user has admin and user permissions.

insert image description here
insert image description here

//  认证
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
    
    
        auth.inMemoryAuthentication()
                .withUser("user")
                .password(new BCryptPasswordEncoder().encode("123456"))
                .authorities("user")
                .and()
                .withUser("admin")
                .password(new BCryptPasswordEncoder().encode("123456"))
                .authorities("user","admin");//权限->字符串  ->页面(配置权限)
    }
    //  授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        http.authorizeHttpRequests()//拦截所有请求
                .antMatchers("/home","/login").permitAll()//某些请求不需要登录->放行某些接口
                .antMatchers("/user").hasAuthority("user")//对页面配置权限
                .antMatchers("/admin").hasAuthority("admin")
                .anyRequest().authenticated();//其他的接口拦截
        http.formLogin();//拦截后跳转到表单页面
    }

4. Create new user.html and admin.html under the templates folder

insert image description here

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>用户页面</h1>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>admin页面</h1>
</body>
</html>

5. Modify the TestController class

insert image description here

    @RequestMapping("user")
    public String user(){
    
    
        return "user.html";
    }
    @RequestMapping("admin")
    public String admin(){
    
    
        return "admin.html";
    }

6. Click Run, and the logged-in user user can access the user page, but cannot access the admin page; the logged-in admin user can access both the user page and the admin page

(1) Log in to the user user

insert image description here
insert image description here
insert image description here

(2) Log in to the admin user

insert image description here
insert image description here
insert image description here

2. Database authentication: Get the user name and password from the database for verification

1. Create a new MyUserService class under the utils folder

insert image description here

package com.example.springboot2.utils;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class MyUserService implements UserDetailsService {
    
    
//   重写登录逻辑  username->登录页面输入的用户名
//   第一步:数据库user表 字段:id username password
//   username去数据库中查询用户(select * from user where username=?)->0、1、多条(注册时->username提示不能重复)
//    第二步:如果是0条->throws UsernameNotFoundException 如果是1条->从用户信息取得密码
//    第三步:用查询出来的密码与用户输入的密码进行比对(框架完成)
//    第四步:根据username 去查询权限roles(id,name)  user表roles表多对多->中间表
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    
    
        String password="123456";//todo 从数据库中查询得到
//       user、admin权限 todo 从数据库中查询得到
        GrantedAuthority authority1=new SimpleGrantedAuthority("user");
        GrantedAuthority authority2=new SimpleGrantedAuthority("admin");
        List<GrantedAuthority> list=new ArrayList<>();
        if (username.equals("user")){
    
    
            list.add(authority1);
        }
        if (username.equals("admin")){
    
    
            list.add(authority1);
            list.add(authority2);
        }
        return new User(username,new BCryptPasswordEncoder().encode(password),list);
    }
}

2. Modify the MySercurityConfig class

insert image description here

package com.example.springboot2.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity
public class MySercurityConfig extends WebSecurityConfigurerAdapter {
    
    
//  认证
//    认证->从数据库中获取用户名和密码进行验证
    @Autowired
    MyUserService myUserService;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
    
    
        auth.userDetailsService(myUserService).passwordEncoder(new BCryptPasswordEncoder());
//        auth.inMemoryAuthentication()
//                .withUser("user")
//                .password(new BCryptPasswordEncoder().encode("123456"))
//                .authorities("user")
//                .and()
//                .withUser("admin")
//                .password(new BCryptPasswordEncoder().encode("123456"))
//                .authorities("user","admin");//权限->字符串  ->页面(配置权限)
    }
    @Bean
    PasswordEncoder passwordEncoder(){
    
    
        return new BCryptPasswordEncoder();
    }
    //  授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        http.authorizeHttpRequests()//拦截所有请求
                .antMatchers("/home","/login").permitAll()//某些请求不需要登录->放行某些接口
                .antMatchers("/user").hasAuthority("user")//对页面配置权限
                .antMatchers("/admin").hasAuthority("admin")
                .anyRequest().authenticated();//其他的接口拦截
        http.formLogin();//拦截后跳转到表单页面
    }
}

3. Click Run, and the logged-in user user can access the user page, but not the admin page; the logged-in admin user can access both the user page and the admin page

(1) Log in to the user user

insert image description here
insert image description here
insert image description here

(2) Log in to the admin user

insert image description here
insert image description here
insert image description here

3. Customize the login page

1. Modify the MySercurityConfig class

insert image description here
insert image description here

  //  授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        http.authorizeHttpRequests()//拦截所有请求
                .antMatchers("/home","/login").permitAll()//某些请求不需要登录->放行某些接口
                .antMatchers("/user").hasAuthority("user")//对页面配置权限
                .antMatchers("/admin").hasAuthority("admin")
                .anyRequest().authenticated();//其他的接口拦截
        http.formLogin()//拦截后跳转到表单页面
                .loginPage("/login")// /login 自己写的页面->默认需要权限
                .loginProcessingUrl("/user/login");//登录提交的请求->框架提供的
    }

2. Modify login.html

insert image description here

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
<h1>登录页面</h1>
<form th:action="@{/user/login}" method="post">
    <div>用户名:<input name="username"></div>
    <div>密码:<input name="password"></div>
    <div><input type="submit" value="提交"></div>
</form>
</body>
</html>

3. Click Run, the login page becomes our custom page

insert image description here

4. Customize the logout page

1. Modify the MySercurityConfig class

insert image description here

    //  授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        http.authorizeHttpRequests()//拦截所有请求
                .antMatchers("/home","/login").permitAll()//某些请求不需要登录->放行某些接口
                .antMatchers("/user").hasAuthority("user")//对页面配置权限
                .antMatchers("/admin").hasAuthority("admin")
                .anyRequest().authenticated();//其他的接口拦截
        http.formLogin()//拦截后跳转到表单页面
                .loginPage("/login")// /login 自己写的页面->默认需要权限
                .loginProcessingUrl("/user/login")//登录提交的请求->框架提供的
                .and()
                .logout()
                .logoutUrl("/logout");//登录提交的请求
    }

2. Create a new mylogout.html under the templates folder

insert image description here

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>退出登录页面</title>
</head>
<body>
<!--框架提供的登出接口-->
<!--/user/login  ->security提供登录验证接口-->
<h1>你确定要退出吗?</h1>
<form th:action="@{/logout}" method="post">
    <button>退出登录</button>
</form>
</body>
</html>

3. Modify the TestController class

insert image description here

    @RequestMapping("mylogout")
    public String mylogout(){
    
    
        return "mylogout.html";
    }

4. Click Run, and the logout page will become our custom page, and return to the login page after logging out

insert image description here
insert image description here

5. File upload

1. Modify application.properties

insert image description here

spring.web.resources.static-locations=classpath:/templates,file:D:/data/

2. Create a new file.html under the templates folder

insert image description here

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form th:action="@{/filecommit}" method="post" enctype="multipart/form-data">
  <div>文件名:<input type="file" name="file"></div>
  <div><input type="submit" value="提交"></div>
</form>
</body>
</html>

3. Create a new FileController class under the controller folder

insert image description here

package com.example.springboot2.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Controller
public class FileController {
    
    
    @RequestMapping("file")
    public String file(){
    
    
        return "file.html";
    }
}

4. Click Run, select the file successfully

insert image description here

insert image description here

5. Modify the MySercurityConfig class and set "/**" to allow all interfaces

insert image description here

    //  授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        http.authorizeHttpRequests()//拦截所有请求
                .antMatchers("/home","/login","/**").permitAll()//某些请求不需要登录->放行某些接口
                .antMatchers("/user").hasAuthority("user")//对页面配置权限
                .antMatchers("/admin").hasAuthority("admin")
                .anyRequest().authenticated();//其他的接口拦截
        http.formLogin()//拦截后跳转到表单页面
                .loginPage("/login")// /login 自己写的页面->默认需要权限
                .loginProcessingUrl("/user/login")//登录提交的请求->框架提供的
                .and()
                .logout()
                .logoutUrl("/logout");//登录提交的请求
    }

6. Modify the FileController class

insert image description here

//   图片、音频、视频一般不直接存数据库    数据库只存文件名字和文件路径
    @RequestMapping("filecommit")
    public String filecommit(MultipartFile file) throws IOException {
    
    
       String filedirs="D:/data/";
       String filename=file.getOriginalFilename();
       file.transferTo(new File(filedirs+filename));
        return "success.html";
    }

7. Click Run, select the file and submit it to the specified path successfully

insert image description here

insert image description here

8. Modify the FileController class. In order to prevent file overwriting problems due to the same file name, set the file name to a random number + file name

insert image description here

//   图片、音频、视频一般不直接存数据库    数据库只存文件名字和文件路径
    @RequestMapping("filecommit")
    public String filecommit(MultipartFile file) throws IOException {
    
    
       String filedirs="D:/data/";
//       String filename=file.getOriginalFilename();
        String filename= UUID.randomUUID()+file.getOriginalFilename();
       file.transferTo(new File(filedirs+filename));
        return "success.html";
    }

9. Click Run, submit the same file twice, the file will not be overwritten

insert image description here
insert image description here
insert image description here
insert image description here

10. Modify the FileController class to display the file

insert image description here


//   图片、音频、视频一般不直接存数据库    数据库只存文件名字和文件路径
    @RequestMapping("filecommit")
    public String filecommit(MultipartFile file, Model model) throws IOException {
    
    
       String filedirs="D:/data/";
//       String filename=file.getOriginalFilename();
        String filename= UUID.randomUUID()+file.getOriginalFilename();
       file.transferTo(new File(filedirs+filename));
        model.addAttribute("filename",filename);
        return "success.html";
    }

11. Modify success.html

insert image description here

12. Click to run, and the picture is displayed successfully

insert image description here
insert image description here

6. Request JSON interface

1. Create a new News class under the pojo folder

insert image description here

package com.example.springboot2.pojo;

import lombok.Data;

@Data
public class News {
    
    
    private int id;
    private String title;
    private String content;
}

2. Create a new JSONController class under the controller folder

insert image description here

package com.example.springboot2.controller;

import com.example.springboot2.pojo.News;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class JSONController {
    
    
//    JSON数据->手机Android端/IOS/小程序
    @RequestMapping("getnews")
    @ResponseBody  //返回JSON数据(特殊格式的字符串)
    public News getNews(){
    
    
        News news=new News();
        news.setId(1);
        news.setTitle("新闻标题");
        news.setContent("新闻内容");
        return news;
    }
}

3. Modify the MySercurityConfig class

insert image description here

//       JSON接口配置
        http.cors();
        http.csrf().disable();

4. Create a new News.html under the templates folder

insert image description here

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<!--ajax请求获取JSON数据->JavaScript 不刷新页面在该页面请求数据-->
<!--ajax ->jQuery-->
<script>
  function getnews(){
      
      
  //  jQuery请求数据
    $.ajax({
      
      
      type:"post",
      url:"http://localhost:8080/getnews",
      contentType:"application/json",
      success:function (res){
      
      
        console.log(res)
          document.getElementById("title").innerText=res.title
          document.getElementById("content").innerText=res.content
      }
    })
  }
</script>
<div id="title">新闻标题</div>
<div id="content">新闻内容</div>
<button onclick="getnews()">获取数据</button>
</body>
</html>

5. Click Run to successfully obtain JSON data

insert image description here
insert image description here

Guess you like

Origin blog.csdn.net/qq_61963074/article/details/127831008