• springboot与安全


    概念:

    • 安全
          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框架)

  • 相关阅读:
    JS 字符串
    JS 变量
    JS 数据类型与运算符
    HTML加载动画实现
    DOM Document.readyState 属性
    html中怎么去掉input获取焦点时候的边框
    原生js获取子元素
    CSS3 Animation动画
    slice,substr和substring的区别
    a链接嵌套无效,嵌套链接最优解决办法
  • 原文地址:https://www.cnblogs.com/MagicAsa/p/10900293.html
Copyright © 2020-2023  润新知