springboot与安全

Easter79
• 阅读 657

概念:

  • 安全

    Spring Security是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型。他可以实现强大的web安全控制。对于安全控制,我们仅需引入spring-boot-starter-security模块,进行少量的配置,即可实现强大的安全管理。

几个类:

       WebSecurityConfigurerAdapter:自定义Security策略

       AuthenticationManagerBuilder:自定义认证策略

       @EnableWebSecurity:开启WebSecurity模式

  1. 应用程序的两个主要区域是“认证”和“授权”(或者访问控制)。这两个主要区域是Spring Security 的两个目标。

  2. 认证”(Authentication),是建立一个他声明的主体的过程(一个“主体”一般是指用户,设备或一些可以在你的应用程序中执行动作的其他系统)。

  3. “授权”(Authorization)指确定一个主体是否允许在你的应用程序执行一个动作的过程。为了抵达需要授权的店,主体的身份已经有认证过程建立。

  4. 这个概念是通用的而不只在Spring Security中。

  • Web&安全

 

  1. 登陆/注销 HttpSecurity配置登陆、注销功能

  2. Thymeleaf提供的SpringSecurity标签支持

    1. 需要引入thymeleaf-extras-springsecurity4

    2. sec:authentication=“name”获得当前用户的用户名

    3. sec:authorize=“hasRole(‘ADMIN’)”当前用户必须拥有ADMIN权限时才会显示标签内容

  3. remember me

    1. 表单添加remember-me的checkbox

    2. 配置启用remember-me功能

  4. CSRF(Cross-site request forgery)跨站请求伪造:HttpSecurity启用csrf功能,会为表单添加_csrf的值,提交携带来预防CSRF;

pom文件引入规则:

<?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 http://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>
       <!-- 这里springbooot必须是2.0.7版本,否则sec:authorize="isAuthenticated()"不起作用-->
        <version>2.0.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.springbootTest</groupId>
    <artifactId>springboot05-security</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot05-security</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
        <thymeleaf-layout-dialect.version>2.3.0</thymeleaf-layout-dialect.version>
        <thymeleaf-extras-springsecurity4.version>3.0.4.RELEASE</thymeleaf-extras-springsecurity4.version>
    </properties>


    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity4 -->
        <!--thmeleaf和springsecurity的依赖-->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
            <version>3.0.4.RELEASE</version>
        </dependency>
        <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>
        <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>

自定义Security策略类写法:

package com.springboottest.security.config;

import org.springframework.context.annotation.Configuration;
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;


@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http);
        //定制请求的授权规则
        http.authorizeRequests().antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("VIP1")
                .antMatchers("/level2/**").hasRole("VIP2")
                .antMatchers("/level3/**").hasRole("VIP3");
        //开启自动配置的登陆功能,效果:如果没有登陆,没有权限就会来到登陆页面
        http.formLogin().usernameParameter("user").passwordParameter("pwd")
                .loginPage("/userlogin");//告诉登录页发送什么请求
        //1.  /login来到登录页
        //2.   /login?error表示登陆失败
        //3.   用户名密码等等更多详细规则
        //4.   默认post形式的/login代表处理登陆
        //5.   一但定制LoginPage;那么LoginPage的post请求就是登陆

        //开启自动配置的注销功能
        http.logout().logoutSuccessUrl("/");//注销成功以后来到首页
        //1.  访问/logout 表示用户注销,清空session
        //2.  注销成功会返回 /login?logout  页面


        //开启记住我功能
        http.rememberMe().rememberMeParameter("remember");
        //登陆成功以后,将cookie发给浏览器,以后登陆带上这个cookie,只要通过检查就可以免登陆
        //点击注销会删除cookie
    }

    //定义认证规则
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //super.configure(auth);
        //   //.passwordEncoder(new MyPasswordEncoder())。
        //这样,页面提交时候,密码以明文的方式进行匹配。看下面解释。
        auth.inMemoryAuthentication().passwordEncoder(new MyPasswordEncoder()).withUser("zhangsan").password("123456").roles("VIP1","VIP2")
                .and()
                .withUser("lisi").password("123456").roles("VIP2","VIP3")
                .and()
                .withUser("wangwu").password("123456").roles("VIP1","VIP3");
    }
}

密码不文明方式报错:

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

解决方法:

这是因为Spring boot 2.0.3引用的security 依赖是 spring security 5.X版本,此版本需要提供一个PasswordEncorder的实例,否则后台汇报错误:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
并且页面毫无响应。
因此,需要创建PasswordEncorder的实现类。
MyPasswordEncoder.class:

@Component
public class MyPasswordEncoder implements PasswordEncoder {


    @Override
    public String encode(CharSequence charSequence) {
        return charSequence.toString();
    }

    @Override
    public boolean matches(CharSequence charSequence, String s) {
        return s.equals(charSequence.toString());
    }
}

welcome.html:

<!DOCTYPE html>
<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>
<div sec:authorize="!isAuthenticated()">
    <h2 align="center">游客您好,如果想查看武林秘籍 <a th:href="@{/userlogin}">请登录</a></h2>
</div>
<div sec:authorize="isAuthenticated()">
    <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>

<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>

<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>

<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>

login.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1 align="center">欢迎登陆武林秘籍管理系统</h1>
    <hr>
    <div align="center">
        <form th:action="@{/userlogin}" method="post">
            用户名:<input name="user"/><br>
            密码:<input name="pwd"><br/>
            <input type="checkbox" name="remember"> 记住我
            <br/>
            <input type="submit" value="登陆">
        </form>
    </div>
</body>
</html>

完整代码见资源(Spring Security框架)

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
3年前
Spring Security使用详解1(基本用法 )
一般项目都会有严格的认证和授权操作,而在Java开发领域常见的安全框架有Shiro和SpringSecurity。本文首先介绍下后者。一、基本用法1、什么是SpringSecurity?SpringSecurity是一个相对复杂的安全管理框架,功能比Shiro更加强大,权限控制细粒度更高,对O
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Stella981 Stella981
3年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Easter79 Easter79
3年前
SpringBoot2.0高级案例(12):整合 SpringSecurity 框架,实现用户权限安全管理
一、Security简介1、基础概念SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring的IOC,DI,AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功
Stella981 Stella981
3年前
SpringBoot2.0高级案例(12):整合 SpringSecurity 框架,实现用户权限安全管理
一、Security简介1、基础概念SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring的IOC,DI,AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功
Wesley13 Wesley13
3年前
ISO27001信息安全管理体系
0x00前言初入甲方,刚开始接触的应该就是ISO27001信息安全管理体系,你拿到的应该就是一整套安全管理类的文档。在甲方,稍微有点规模的公司很注重制度和流程,岗位职责分工明细,那么这些安全管理制度,就是你所能掌控的游戏规则,几个人的信息安全部生存之道。0x01ISO27001简介ISO/IEC27001信息安全管理体系
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k