Springboot整合Security

步骤

1. 创建maven项目

![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414134328346.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

2.导入相关依赖

![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414134637614.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
    </parent>

    <dependencies>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--thymeleaf集成springsecurity4-->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
            <version>3.0.2.RELEASE</version>
        </dependency>
        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

4. 创建一些简单的页面

![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414134753681.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

5. 创建controller和启动类

![在这里插入图片描述]( https://img-blog.csdnimg.cn/2020041413521835.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

@Controller
public class routerController {
    @RequestMapping({"/","index"})
    public String index(){//跳转首页的方法
        return "index";
    }
    @RequestMapping("/add")
    public String add(){//跳转添加页的方法
        return  "add";
    }
    @RequestMapping("/delete")
    public String delete(){//跳转删除页的方法
        return  "delete";
    }
    @RequestMapping("/toLogin")
    public String toLogin(){//跳转登录页的方法
        return  "login";
    }
}

![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414135346195.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

6. 配置授权信息

让添加和删除需要有对应的权限才可以访问

1. 导入Secuity依赖

![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414135640302.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

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

2. 编写配置类 继承WebSecurityConfigurerAdapter类 加上注解 @EnableWebSecurity 启动security

![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414135738681.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
重写父类的configure方法 实现授权操作

3. 首页可以所有人访问 如下配置

![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414140031473.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

 @Override
    protected void configure(HttpSecurity http) throws Exception {
        //首页所有人可以访问 permitAll()所有/请求能通过
        http.authorizeRequests()
                .antMatchers("/").permitAll();

    }

4. 添加和删除请求需要有权限才能访问

![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414140246833.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

 @Override
    protected void configure(HttpSecurity http) throws Exception {
        //首页所有人可以访问 permitAll()所有/请求能通过
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/add").hasRole("addRole") //添加请求需要addRole权限
                .antMatchers("/delete").hasRole("deleteRole");//删除请求需要deleteRole权限

    }

访问发现 报错 403 权限不足
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414140406691.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

5. 配置没有权限自动跳到默认登录页

开启登录页面 formLogin()
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414140534251.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
重新访问add请求 发现跳进了security默认提供的登录页
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414140631439.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

6. 配置认证 添加虚拟用户

![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414141106623.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())//必须开启加密验证 才能访问成功 不然登录失败
                //添加一个joker_dj用户 账号为joker_dj 密码为加密的密码new BCryptPasswordEncoder().encode("123456")  拥有的权限为 addRole
                .withUser("joker_dj").password(new BCryptPasswordEncoder().encode("123456")).roles("addRole");
    }

点击添加跳进登录页面 输入账号密码
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414141251211.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
访问成功

7. 开启注销功能

![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414141418437.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

//开启注销功能 默认的url:/logout
        http.logout();

前端页面访问/logout
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414141515835.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
点击注销
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414141555339.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
注销后自动跳进登录页面
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414141622947.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
配置注销后跳进指定地页面
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414141740615.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

 //logoutSuccessUrl() 注销后跳进的url
        http.logout()
        .logoutSuccessUrl("/");

8. 控制页面的显示隐藏 (权限控制)

注意:springboot2.0.9版本以后的不支持security标签,我们需要下降版本才能看到效果

![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414142136293.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
在index.html中控制链接的显示隐藏
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414142901293.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

<!--获取登录的用户名 默认为:anonymousUser-->
<div>
    <span sec:authentication="name"></span>
</div>
<!--拥有addRole权限显示-->
<div sec:authorize="hasRole('addRole')">
    <a th:href="@{/add}">添加</a>
</div>
<!--拥有deleteRole权限显示-->
<div sec:authorize="hasRole('deleteRole')">
    <a th:href="@{/delete}">删除</a>
</div>
<!--未登录显示 登录后隐藏-->
<div sec:authorize="!isAuthenticated()">
    <a th:href="@{/toLogin}">登录</a>
</div>
<!--未登录隐藏 登录后显示-->
<div sec:authorize="isAuthenticated()">
    <a th:href="@{logout}">注销</a>
</div>

启动访问 只能看到登录页面
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414142917276.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
尝试登录·
注意:我们需要访问/login才能进行访问 还没有配置自己的登陆页面
由于版本过低 默认登录页面变成了这样
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414143117186.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
输入用户名密码
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414143217381.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
登录成功后 显示用户名和添加的链接
登录链接也隐藏了 删除链接没有权限也被隐藏

点击注销 会发现报错
原因 security怕收到csrf攻击 开启了csrf防御 需要手动关闭
什么是csrf攻击 可以看这篇文章 https://blog.csdn.net/xiaoxinshuaiga/article/details/80766369
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414143358171.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

9. 关闭csrf

![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414143724282.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

 //关闭csrf
        http.csrf().disable();

再次注销可以成功了

10. 定制自己的登录页面

![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414143951301.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

//定制自己的登录页面
        http.formLogin()
                .loginPage("/toLogin");

输入用户名密码 点击登录按钮 会发现登陆失败 找不到 /login请求
![在这里插入图片描述]( https://img-blog.csdnimg.cn/2020041414410911.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414144144811.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
解决:
第一种方式 把form表单的action改成和loginPage()的地址一样
注意:提交方式一定要是post
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414144232864.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
第二种方式:
配置登录请求的url
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414144437949.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

//.loginProcessingUrl("/login"); 验证登录请求的url
        http.formLogin()
                .loginPage("/toLogin")
                .loginProcessingUrl("/login");

登录成功
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414144524510.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

11. 记住我功能的开启

配置类:
![在这里插入图片描述]( https://img-blog.csdnimg.cn/2020041414472476.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
登录页:
![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200414144805598.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)

<form th:action="@{/login}" method="post">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="checkbox" name="remberme"> 记住我
    <input type="submit"value="登录">
</form>

再次登录 开启记住我
查看Cookeis 会发现Security把我们的用户信息存到了cookies中![在这里插入图片描述]( https://img-blog.csdnimg.cn/2020041414492871.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2pva2VyZGoyMzM=,size_16,color_FFFFFF,t_70)
ok到此结束
注意点:版本问题,csrf问题,post提交问题 少踩坑

posted @ 2020-04-14 14:55  joker_dj  阅读(532)  评论(0)    收藏  举报