springboot SpringSecurity(安全)

官网

https://docs.spring.io/spring-security/site/docs/5.2.1.RELEASE/reference/htmlsingle/#saml2

一、安全?

1、非功能性需求

2、设计之初,考虑安全

二、功能

认证、授权

三、使用

1、导入thymeleaf

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>

2、关闭模板引擎

spring:
  thymeleaf:
    cache: false

3、导入 security

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

四、用户认证和授权

1、创建config文件夹,创建SecurityConfig.java

固定的架子

package com.wt.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 {
        super.configure(http);
    }
}

2、示例

package com.wt.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 {
    // 授权的规则
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 首页所有人可以访问,功能页只有对应有权限的人才能访问
        // "/" 首页
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        // 没有权限默认到登录页,开启登录页面
        http.formLogin();
    }

    // 认证的规则
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // auth.jdbcAuthentication() 连接数据库
        // 内存
        // 通过 and withUser 添加用户
        // 密码加密
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("wt").password(new BCryptPasswordEncoder().encode("123")).roles("vip1", "vip2")
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123")).roles("vip1", "vip2", "vip3");
    }
}

JDBC授权

import javax.sql.DataSource;
@Autowired
private DataSource dataSource;

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    // ensure the passwords are encoded properly
    UserBuilder users = User.withDefaultPasswordEncoder();
    auth
        .jdbcAuthentication()
            .dataSource(dataSource)
            .withDefaultSchema()
            .withUser(users.username("user").password("password").roles("USER"))
            .withUser(users.username("admin").password("password").roles("USER","ADMIN"));
}

springboot 配置 DataSource

a、导入包

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

<!--数据库驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.20</version>
</dependency>

b、yml文件

spring:
  datasource:
    password: test
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&useSSL=false
    driver-class-name: com.mysql.jdbc.Driver
    username: test

五、注销和权限控制

1、注销

// 链式编程
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // 授权的规则
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 首页所有人可以访问,功能页只有对应有权限的人才能访问
        // "/" 首页
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        // 没有权限默认到登录页,开启登录页面
        http.formLogin();

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

关于logout的url和其它具体功能看源码

2、与thymeleaf整合

a、导入包

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity4</artifactId>
    <version>3.0.2.RELEASE</version>
</dependency>

b、降版本(如果能用,可以不用降)

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
</parent>

c、config文件夹

package com.wt.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 {

    // 授权的规则
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 首页所有人可以访问,功能页只有对应有权限的人才能访问
        // "/" 首页
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        // 没有权限默认到登录页,开启登录页面
        http.formLogin();
        // logout 失败的可能原因
        http.csrf().disable();
        // 开启注销
        http.logout();
    }

    // 认证的规则
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // auth.jdbcAuthentication() 连接数据库
        // 内存
        // 通过 and withUser 添加用户
        // 密码加密
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("wt").password(new BCryptPasswordEncoder().encode("123")).roles("vip1", "vip2")
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123")).roles("vip1", "vip2", "vip3");
    }
}

d、html文件

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--未登陆,显示 login-->
    <div sec:authorize="!isAuthenticated()">
        <button>login</button>
    </div>

    <!--已经登录,显示用户名和角色-->
    <div sec:authorize="isAuthenticated()">
        <a class="item">
            用户名: <span sec:authentication="name"></span>
        </a>
    </div>

    <!--已经登录,显示 logout-->
    <div sec:authorize="isAuthenticated()">
        <button>logout</button>
    </div>
</body>
</html>

e、菜单的动态实现

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--有vip1的权限, 显示-->
    <div sec:authorize="hasRole('vip1')">
        <p>一会儿翅膀碰着波浪,一会儿箭一般地直冲向乌云,它叫喊着</p>
    </div>
</body>
</html>

3、开启记住我功能

config文件夹

package com.wt.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 {

    // 授权的规则
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 首页所有人可以访问,功能页只有对应有权限的人才能访问
        // "/" 首页
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        // 没有权限默认到登录页,开启登录页面
        http.formLogin();
        // logout 失败的可能原因
        http.csrf().disable();
        // 开启注销
        http.logout();
        // 开启记住我功能
        http.rememberMe();
    }
}

六、使用自定义页面

1、使用自定义的登录页面

// 指定自定义的登录页面
http.formLogin().loginPage("/myLogin");

fromLogin()后面的链式编程与前端的form表单配合使用

.usernameParameter(&quot;username&quot;) // default is username
.passwordParameter(&quot;password&quot;) // default is password

2、记住我功能

与form表单配合使用

http.rememberMe().rememberMeParameter("myRemember");

 

posted @ 2020-08-10 16:57  市丸银  阅读(267)  评论(0编辑  收藏  举报