200_SpringSecurity


SpringSecurity简介

image.png
image.png
image.png

SpringSecurity环境搭建

创建项目

image.png
image.png
image.png

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.qing</groupId>
    <artifactId>springboot-06-security</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-06-security</name>
    <description>springboot-06-security</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

添加thymeleaf依赖

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

配置:关闭thymeleaf缓存,方便调试,不需要每次修改都重启,生产环境开启

image.png

spring.thymeleaf.cache=false

添加页面和静态资源

image.png

添加controller

package com.qing.controller;

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

@Controller
public class RouterController {

    @RequestMapping({"/","/index"})
    public String index() {
        return "index";
    }

    @RequestMapping("/toLogin")
    public String toLogin() {
        return "views/login";
    }

    @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;
    }
}

测试

image.png

认证和授权

image.png

添加依赖spring-boot-starter-security

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

创建SecurityConfig,继承WebSecurityConfigurerAdapter

image.png

授权 configure(HttpSecurity http)

源码注释

protected void configure(HttpSecurity http) throws Exception {
	http.authorizeRequests()
        .antMatchers("/**").hasRole("USER")
        .and().formLogin();
}

protected void configure(HttpSecurity http) throws Exception {
	http.authorizeRequests()
        .antMatchers("/admin/**").hasRole("ADMIN")
		.antMatchers("/**").hasRole("USER")
        .and().formLogin();
}
package com.qing.config;

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;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    /**
     * 授权
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 链式编程
        // 授权首页所有人可以访问,功能页只有有权限的人才能访问
        // 请求授权规则
        http.authorizeRequests() // 授权请求
                .antMatchers("/").permitAll() // /请求,所有用户可以访问
                .antMatchers("/level1/**").hasRole("vip1") // /level1/**请求,有角色vip1的才能访问
                .antMatchers("/level2/**").hasRole("vip2") // /level2/**请求,有角色vip2的才能访问
                .antMatchers("/level3/**").hasRole("vip3"); // /level3/**请求,有角色vip3的才能访问
    }
}

没有权限,报403
image.png

http.formLogin(); // 没有权限默认会跳到登录页面/login,需要开启登录的页面

package com.qing.config;

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;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 链式编程
        // 授权首页所有人可以访问,功能页只有有权限的人才能访问
        // 请求授权规则
        http.authorizeRequests() // 授权请求
                .antMatchers("/").permitAll() // /请求,所有用户可以访问
                .antMatchers("/level1/**").hasRole("vip1") // /level1/**请求,有角色vip1的才能访问
                .antMatchers("/level2/**").hasRole("vip2") // /level2/**请求,有角色vip2的才能访问
                .antMatchers("/level3/**").hasRole("vip3"); // /level3/**请求,有角色vip3的才能访问

        // 开启登录,没有权限默认会跳到登录页面/login
        http.formLogin();
    }
}

image.png

认证 configure(AuthenticationManagerBuilder auth)

源码注释

protected void configure(AuthenticationManagerBuilder auth) throws Exception {
	auth.inMemoryAuthentication()
        .withUser("user").password("password").roles("USER")
		.and()
        .withUser("admin").password("password").roles("ADMIN", "USER");
}
package com.qing.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;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 授权
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 链式编程
        // 授权首页所有人可以访问,功能页只有有权限的人才能访问
        // 请求授权规则
        http.authorizeRequests() // 授权请求
                .antMatchers("/").permitAll() // /请求,所有用户可以访问
                .antMatchers("/level1/**").hasRole("vip1") // /level1/**请求,有角色vip1的才能访问
                .antMatchers("/level2/**").hasRole("vip2") // /level2/**请求,有角色vip2的才能访问
                .antMatchers("/level3/**").hasRole("vip3"); // /level3/**请求,有角色vip3的才能访问

        // 开启登录,没有权限默认会跳到登录页面/login
        http.formLogin();
    }

    /**
     * 认证
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 内存中认证,正常数据应该从数据库读取
        auth.inMemoryAuthentication()
                // 在SpringSecurity5.0+ 新增了很多的加密方法
                .passwordEncoder(new BCryptPasswordEncoder()) // 密码加密方式,不加密会报错
                .withUser("zhangsf").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
                .and() // 拼接下一个认证
                .withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                .and()
                .withUser("zhangdl").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3");
    }
}

测试

用户“zhangsf”登录,有roles("vip1","vip2")的权限,应该可以访问/level1/和/level2/,不能访问/level3/**
image.png
image.png
image.png
image.png
image.png

JDBC

image.png

注销

开启注销

<!--注销-->
<a class="item" th:href="@{/logout}">
    <i class="sign-out icon"></i> 注销
</a>
// 开启注销
http.logout();
package com.qing.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.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 授权
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 链式编程
        // 授权首页所有人可以访问,功能页只有有权限的人才能访问
        // 请求授权规则
        http.authorizeRequests() // 授权请求
                .antMatchers("/").permitAll() // /请求,所有用户可以访问
                .antMatchers("/level1/**").hasRole("vip1") // /level1/**请求,有角色vip1的才能访问
                .antMatchers("/level2/**").hasRole("vip2") // /level2/**请求,有角色vip2的才能访问
                .antMatchers("/level3/**").hasRole("vip3"); // /level3/**请求,有角色vip3的才能访问

        // 开启登录,没有权限默认会跳到登录页面/login
        http.formLogin();

        // 开启注销
        http.logout();
    }

    /**
     * 认证
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 内存中认证,正常数据应该从数据库读取
        auth.inMemoryAuthentication()
                // 在SpringSecurity5.0+ 新增了很多的加密方法
                .passwordEncoder(new BCryptPasswordEncoder()) // 密码加密方式,不加密会报错
                .withUser("zhangsf").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
                .and() // 拼接下一个认证
                .withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                .and()
                .withUser("zhangdl").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3");
    }
}

image.png
image.png
image.png

开启注销,并跳转指定页面

// 开启注销,注销后跳转到首页
http.logout().logoutSuccessUrl("/");
package com.qing.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.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 授权
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 链式编程
        // 授权首页所有人可以访问,功能页只有有权限的人才能访问
        // 请求授权规则
        http.authorizeRequests() // 授权请求
                .antMatchers("/").permitAll() // /请求,所有用户可以访问
                .antMatchers("/level1/**").hasRole("vip1") // /level1/**请求,有角色vip1的才能访问
                .antMatchers("/level2/**").hasRole("vip2") // /level2/**请求,有角色vip2的才能访问
                .antMatchers("/level3/**").hasRole("vip3"); // /level3/**请求,有角色vip3的才能访问

        // 开启登录,没有权限默认会跳到登录页面/login
        http.formLogin();

        // 开启注销
//        http.logout();
        // 开启注销,注销后跳转到首页
        http.logout().logoutSuccessUrl("/");
    }

    /**
     * 认证
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 内存中认证,正常数据应该从数据库读取
        auth.inMemoryAuthentication()
                // 在SpringSecurity5.0+ 新增了很多的加密方法
                .passwordEncoder(new BCryptPasswordEncoder()) // 密码加密方式,不加密会报错
                .withUser("zhangsf").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
                .and() // 拼接下一个认证
                .withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                .and()
                .withUser("zhangdl").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3");
    }
}

页面权限控制

security-thymeleaf整合包

image.png
image.png

页面显示权限控制:登录认证显示,未登录未认证不显示

image.png
image.png
sec标签
image.png
注:版本使用2.0.9及以下,高版本不支持
image.png
image.png

页面显示权限控制:指定角色显示页面

image.png
image.png
image.png

记住我

// 开启记住我,实际就是cookie,默认保存两周,关闭浏览器,下次打开还是登录状态
http.rememberMe();
package com.qing.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.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 授权
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 链式编程
        // 授权首页所有人可以访问,功能页只有有权限的人才能访问
        // 请求授权规则
        http.authorizeRequests() // 授权请求
                .antMatchers("/").permitAll() // /请求,所有用户可以访问
                .antMatchers("/level1/**").hasRole("vip1") // /level1/**请求,有角色vip1的才能访问
                .antMatchers("/level2/**").hasRole("vip2") // /level2/**请求,有角色vip2的才能访问
                .antMatchers("/level3/**").hasRole("vip3"); // /level3/**请求,有角色vip3的才能访问

        // 开启登录,没有权限默认会跳到登录页面/login
        http.formLogin();

        // 开启注销
//        http.logout();
        // 开启注销,注销后跳转到首页
        http.logout().logoutSuccessUrl("/");

        // 开启记住我,实际就是cookie,默认保存两周,关闭浏览器,下次打开还是登录状态
        http.rememberMe();
    }

    /**
     * 认证
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 内存中认证,正常数据应该从数据库读取
        auth.inMemoryAuthentication()
                // 在SpringSecurity5.0+ 新增了很多的加密方法
                .passwordEncoder(new BCryptPasswordEncoder()) // 密码加密方式,不加密会报错
                .withUser("zhangsf").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
                .and() // 拼接下一个认证
                .withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                .and()
                .withUser("zhangdl").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3");
    }
}

image.png
image.png

定制登录页

image.png

// 开启登录,自定义登录页时
http.formLogin()
        .loginPage("/toLogin") // 设置登录页
        .usernameParameter("user") // 设置登录用户名传参名称
        .passwordParameter("pwd") // 设置登录密码传参名称
        .loginProcessingUrl("/login"); // 设置登录接口

// 开启记住我,自定义登录页时,设置记住我标签传参名称
http.rememberMe().rememberMeParameter("remember");
package com.qing.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.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 授权
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 链式编程
        // 授权首页所有人可以访问,功能页只有有权限的人才能访问
        // 请求授权规则
        http.authorizeRequests() // 授权请求
                .antMatchers("/").permitAll() // /请求,所有用户可以访问
                .antMatchers("/level1/**").hasRole("vip1") // /level1/**请求,有角色vip1的才能访问
                .antMatchers("/level2/**").hasRole("vip2") // /level2/**请求,有角色vip2的才能访问
                .antMatchers("/level3/**").hasRole("vip3"); // /level3/**请求,有角色vip3的才能访问

        // 开启登录,没有权限默认会跳到登录页面/login
//        http.formLogin();
        // 开启登录,自定义登录页时
        http.formLogin()
                .loginPage("/toLogin") // 设置登录页
                .usernameParameter("user") // 设置登录用户名传参名称
                .passwordParameter("pwd") // 设置登录密码传参名称
                .loginProcessingUrl("/login"); // 设置登录接口
        // 开启注销
//        http.logout();
        // 开启注销,注销后跳转到首页
        http.logout().logoutSuccessUrl("/");

        // 开启记住我,实际就是cookie,默认保存两周,关闭浏览器,下次打开还是登录状态
//        http.rememberMe();
        // 开启记住我,自定义登录页时,设置记住我标签传参名称
        http.rememberMe().rememberMeParameter("remember");
    }

    /**
     * 认证
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 内存中认证,正常数据应该从数据库读取
        auth.inMemoryAuthentication()
                // 在SpringSecurity5.0+ 新增了很多的加密方法
                .passwordEncoder(new BCryptPasswordEncoder()) // 密码加密方式,不加密会报错
                .withUser("zhangsf").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
                .and() // 拼接下一个认证
                .withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                .and()
                .withUser("zhangdl").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3");
    }
}

image.png

posted @   清风(学习-踏实)  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示