spring boot2.0之Spring Security登录权限认证

没错,又是spring boot2.0和1.0之间版本不同的问题!互联网的东西更新的是真的快,很多东西才过了一段时间,用法就不一样了,最近在学习Spring Security这个安全框架的时候又遇到了,很苦逼。

首先,先简单介绍一下(很简单的介绍,想要详细了解这个框架的话,还是去看官方文档或者网上的中文文档,里面都有详细介绍)

Spring Secutity:一个能够为基于Spring的企业应用系统提供声明式的安全訪问控制解决方式的安全框架(简单说是对访问权限进行控制嘛),应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。

下面我们来详细了解一下 Spring Security 的用户认证和用户授权功能。

一、搭建 Spring Secutity 环境(spring-boot 2.1.6,spring-security-xxx 5.1.5.RELEASE,都是maven下载最新版本)

1、使用IDEA(旗舰版)快速生成 Secutity环境,并且导入 thymeleaf 模板引擎,方便后面步骤的展开

        小提示:IDEA大家最好都去用旗舰版,虽然需要破解,可能费点功夫,但是功能比社区版多很多,笔者亲身使用过社区版,为了跟上旗舰版的功能,装了很多插件,有时候都装不上,破解的方法网上百度一大把,笔者这里就不过多描述了。

笔者这里的环境配置基本是最新版本,也是因为最新版本,所以会有很多新的东西,新的语法,学习过程中可能会有很多问题,但是由于自己比较喜欢学新的东西,看文档,所以一直坚持着用最新版本的东西来学习。

二、编写用户登录过滤器

核心:(1)@EnableWebSercurity 注解用于开启 Spring Security,禁用Boot的默认Security配置,配合@Configuration启用自定义配置;

           (2)继承 WebSecurityConfigurerAdapter 构造器类,它提供了(http,web,auth)三个configure方法,用于我    们下面用户登录授权等操作;

(3)开启spring sercurity自动配置的登录功能:http.formLogin( ) 和自动配置的注销功能 http.logout( )。

@EnableWebSecurity // 启动 Spring security
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    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");
                // 设置对应的url是全部放行还是要特定的角色才能进入

        // 开启自动配置的登录功能,效果:如果没有登录,没有权限就会来到登录页面
           http.formLogin();

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

    }

 三、编写用户授权认证规则

 因为Spring security 5.0中新增了多种加密方式,也改变了密码的格式;现如今Spring Security中密码的存储格式是“{id}…………”。前面的id是加密方式,id可以是bcrypt、sha256等,后面跟着的是加密后的密码; 也就是说,程序拿到传过来的密码的时候,会首先查找被“{”和“}”包括起来的id,来确定后面的密码是被怎么样加密的,如果找不到就认为id是null;

笔者的解决办法是在inMemoryAuthentication()方法的后面加上:passwordEncoder(new BCryptPasswordEncoder()) 如下

auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
// 定义认证规则
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // super.configure(auth);
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("zhangsan").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP1", "VIP2")
                .and()
                .withUser("lisi").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP2", "VIP3")
                .and()
                .withUser("wangwu").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP1", "VIP3");
    }


            如果你用的是在数据库中存储用户名和密码,那么一般是要在用户注册时就使用BCrypt编码将用户密码加密处理后存储在数据库中。并且修改configure()方法,加入".passwordEncoder(new BCryptPasswordEncoder())",保证用户登录时使用bcrypt对密码进行处理再与数据库中的密码比对。
             auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder())

四、Spring Security5 框架和 thymeleaf 模板引擎相结合,完成最终的用户验证和用户权限控制

1、引入 thymeleaf 和 spring secutrity 的整合包(很重要,笔者就是疏忽,导致卡壳)

  <!-- 一定要导入这个thymeleaf和springsecurity5整合的依赖包!!! -->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
            <version>3.0.4.RELEASE</version>
        </dependency>

2、在要构建用户权限控制的html页面上方引入:

         xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"

                 模板框架,这里需要注意的一个点是,我的 security 是5.0的版本,所以 thymeleaf-extras-springsecurity5 后缀这里的版本号应为 5 ,网上很多文章都说让我们降低版本,改成4,其实也可以,但是相应 pom.xml 文件里面也要对版本进行更改,笔者这里因为不服输,就是要用新版本,所以才会弄了很长时间。

3、使用 sec: 标签进行权限控制

一开始笔者是不会用 sec:标签的,于是上去了spring security的官方文档上面去看,选择自己的版本

          然后使用了 <sec:authorize> 这样的写法,发现并不行,又进入卡壳状态,最终经过CSDN某位大佬的文章解救,得出以下结果:完美实现了用户权限的控制。

<h1 align="center">欢迎光临武林秘籍管理系统</h1>
<div sec:authorize="isAnonymous()"> <!-- 如果当前主体是匿名用户,则返回true -->
	<h2 align="center">游客您好,如果想查看武林秘籍 <a th:href="@{/login}">请登录</a></h2>
</div>

<div sec:authorize="isAuthenticated()"> <!-- 如果用户不是匿名用户,则返回true,也就是登录状态-->
	<h2><span sec:authentication="principal.username" />,您好,您的权限为有:
		<span sec:authentication="principal.authorities"/></h2>
	<form th:action="@{/logout}" method="post"><!-- 因为要退出,默认方法要是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:authoize access="isAnonymous()"> 再标签里加上 access 属性的写法,笔者在当前的版本下试验过了,并不行,所以请各位读者一定要注意版本问题,毕竟一代版本一代神,很多东西都不一样;好了今天就到这里,下次再会。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值