SpringBoot基于SpringSecurity表单登录和权限验证的示例

一、简介

上篇介绍了一个自己做的管理系统,最近空闲的时间自己在继续做,把之前登录时候自定义的拦截器过滤器换成了基于SpringSecurity来做,其中遇到了很多坑,总结下,大家有遇到类似问题的话就当是为大家闭坑吧。

二、项目实现功能和成果展示

首先来看下登录界面:这是我输入的一个正确的信息,点击登录后SpringSecurity会根据你输入的用户名和密码去验证是否正确,如果正确的话就去你定义的页面,我这里定义的是查询教师信息页面。来看下代码吧。

三、准备工作(前台页面、实体类)

实体类Teacher:字段主要有id、name、sex、email、schedule_Id、password、phone,上面都加了Hibernate的验证,其他字段大家可以自己写,然后生成getter和setter方法

再来看下前台页面,前台我使用的是一个BootStrap的页面,模板语言使用的是Thymeleaf,当然为了能够在页面支持security的语法需要在上面加入一个security的引入标签

index.html"页面

index.html中登录信息:需要注意的是我的表单是提交到/teacher/login这个路由上,然后就是字段中的name属性必须要和你Teacher实体类中的字段名一致,不然页面数据传不到后台。这里只截图2个字段吧太长了其他的字段都一样该好名字就行

然后我们再来看下TeacherController中的代码:

这里面的代码是我之前没使用SpringSecurity的时候写的,现在注释掉了,当我们登录成功之后就会到/query这个路由下的方法去执行,也就是执行查询教师信息,先不看query方法,我们现在先来对接SpringSecurity,让它先帮我们来进行index中用户名和密码的登录验证,然后再看query方法

四、使用SpringSecurity进行表单验证登录

要想使用SpringSecurity就需要现在pom.xml中加入SpringSecurity的依赖,你可以指定版本号也可以不指定,我这里没有指定

注意:当你引入SpringSecurity之后当你再次去启动项目的时候,SpringSecurity自动会给你跳到一个对话框,让你输入账号和密码,这里的用户名是user,密码在你启动的时候它会有一个加密的密文,你只需要复制进去就可以登录。

接下来我们要想实现自定义的表单验证登录和其他高级功能就需要使用配置类来配置,在SpringBoot中新建一个配置类,让它来继承WebSecurityConfigurerAdapter,然后重写里面的configure方法,在里面定义我们的逻辑,来看下代码吧:

上面的是我项目中的配置,有些是本文用不到的,分别解释下:从开始来说,http.formLogin的作用是使用form表单进行登录,也就是我们的index页面。当然你也可以使用Batic登录,就是之前说的默认给你的登录信息界面。

上面的URL是我们的index页面的数据也就是登录的字段数据,当时我们提交的路径是/teacher/login,而我们这里的配置意味着让SpringSecurity去处理我们index表单数据,你这样写SpringSecurity就知道对这个路径进行登录验证处理。

请注意下面的代码因为有坑:

可以看到我这边配置了2个Mathchers,如果不配置的话会出现什么状况呢?你可能会遇到下面的这种错误

什么意思呢?我先来简化出来一个简单的配置,下面的这段配置的意思:处理登录的Url为/teacher/login,对任何的请求都进行验证,下面的csrf先忽略,那么上面的定向次数太多是怎么来的呢?当你点击登录之后,SpringSecurity会去处理/teacher/login这个请求,然后它发现这个请求也是需要验证的,于是乎就进入了死循环,它一直在验证。。。

要想解决这个问题,其实也很简单,就是给它弄一个匹配器,告诉SpringSecurity,我在访问这个路径的时候你要放行不要拦截,比如说你可以这么写:.antMatchers("/teacher/login").permitAll(),有的朋友可能看了我上面的代码,你并不是这么写的啊,你没有对/teacher/login放行啊!还记得我上面说的吗在们登录成功之后也就是/teacher/login验证之后是要去执行/query方法去查询教师信息的,因此我的匹配器匹配的是/query,所以我这么写.antMatchers("/query").hasAnyRole("admin","stu")的时候并没有permitAll,是因为后面的hasRole,表示看你当前登录的用户有没有admin或者是stu这样的角色,有的话我就放行没有的话就不放行,有的朋友可能会说那怎么角色该在哪里定义呢?下面我来看一下

五、角色匹配

这个时候我们需要重写Adapter的另外一个configure方法注意这个方法的参数类型是AuthenticationManagerBuilder,它是一个认证管理构建器,可以帮我们构建出你要对什么东西进行认证,比如角色、用户、密码,我们先来写一个内存认证,后台会说怎么连数据库去认证权限

上面这段代码的意思是:我的认证用户为安安,密码为:123123,安安的角色是admin,只有这些信息正确之后我才让你认证成功,去执行下面的逻辑。我们来看下演示:

这就是代表登录成功了,至于上面的角色显示什么的我都会说到,那么我们来换一个,刚才/query中的hasRole里面是admin和stu,我把admin去掉看下能登录成功吗?需要有一个stu的角色才能在登录成功之后查看信息,而我们现在的用户名和密码都正确的情况下,角色不正确能够成功吗?

可以看到即使是使用了上面正确的用户名和密码登录,但是提示没有权限,这个页面是我自定义的错误页面,你的可能会提示403没有这些样式。

六、从数据库中读取角色来验证

在真实的开发中,我们肯定是不会将用户信息这种东西放到内存中去的,肯定时从数据库中读取的,我在数据库中新建了一张表,教师角色表,我们就从这张表读取角色信息然后交给SpringSecurity去判断角色

实体类这里就不截图了,然后我们在TeacherRoleRepository中有这么一个方法,就是根据TeacherId去查询教师的角色,为了方便我这里就不去新建什么Service了,直接就TeacherRoleRepository调用里面的findByTeacherId()方法

接下来,我们编写一个TeacherDetailsService它实现一个UserDetailsService接口,UserDetailsService里面只有一个方法就是loadUserByUsername(String username),这么方法是干嘛的呢,是根据你提供的用户名它去查出用户的具体信息,然后返回一个User对象(SpringSecurity中的User对象),这个User对象会携带着你需要验证的信息去验证,如果通过的话就进行放行,那么User对象都会有哪些参数呢?来看下源码:你可以只传这三个参数,当然你也可以传剩下的那些,比如密码是否被锁定,账户是否被冻结,是否传这些看你业务需要的,当然你可以自定义一个类,然后让它去实现UserDetails,实现里面的这些方法,因为这7个方法都是UserDetails接口里的。

在我的项目里没有重写,直接携带着用户信息返回了User对象,需要的三个参数中第一个参数username已经有了,是SpringSecurity为我们获取的,至于怎么获取的,我们在最后的文章中说原理的时候再谈,然后就是password,有了username的话拿到password就很简单,我们自定义了一个TeacherRepository类,里面有一个根据name获取信息的方法,然后直接获取密码就好,最关键的是第三个参数,这个参数的意思是让我们传入授权,在我们这里就是角色,首先第一步我们先根据教师id获取到角色信息,这个不难,关键是角色信息是一个List,因为一个人可能有多个角色,意味着我们可以很简单的拿到一个角色列表,然后我们需要用到一个类,这个类是GrantedAuthority它表示已经被授权的权限,我们来构建一个GrantedAuthority类型的数组,用来表示已经被授权的角色,然后我们来实例化一个它的实现类SimpleGrantedAuthority这个类会接受一个String类型的role,然后去进行授权。

什么意思呢?大概的流程是这样的,首先我们从数据库中读取到了这个用户对应的角色,它是一个列表,记着我们要把这个列表中的值传给SpringSecurity去判断,看我这个列表里面有没有你需要认证的角色,如SpringSecurity需要一个admin角色才可以访问/query。这时数据库中这个用户有一个角色为admin,那么就让它访问/query,GrantedAuthority、SimpleGrantedAuthority它们可以简单理解为是用来帮你把数据库中的角色交给SpringSecurity来验证。

代码如下:

然后在我们之前的配置类中的configure方法就要改一下,因为我们之前是从内存中读取的,现在是从数据库中读取出来的

我们需要验证的信息都在TeacherDetailsService中,因此我们还需要实例化一个TeacherDetailsService

细心的朋友可能会看到auth中还有一个passwordEncoder,这个下篇里面说,如果在SpringSecurity中使用自定义数据库的加密方式,需要注意的是我们这样写完之后会报错,当时我也很懵,后来查阅了好多资料才发现的,角色认证的一个大坑!!

经过上面的信息认证之后SpringSecurity发现我们输入的信息是对的,但是再次登录后还是会报错403,告诉你没有认证成功,没有对应的权限,这是为什么?后来查阅了SpringSecurity的API发现有这么一段

就是说当你从数据库中查到角色之后,虽然SimpleGrantedAuthority接收的是一个字符串角色,但是最终你返回的User对象中Collection<? extends GrantedAuthority> authorities这里需要的格式是ROLE_A这种格式,所有你需要在传给User对象之前,将角色名称前加一个ROLE_,比如我下面的这样:RoleName就是我定义的ROLE_字符串,这样才能够被SpringSecurity所认证。

之前看有的文章说是因为hasRole需要在前面加ROLE_才可以,所以在配置文件中试了一下ROLE_ADMIN不好使,而且查阅官方API发现hashRole和hashAnyRole都不需要前面写ROLE_

原来之所以不用写是以为在SimpleGrantedAuthority传入之后的格式中有了ROLE_限定

到此这篇关于SpringBoot基于SpringSecurity表单登录和权限验证的示例的文章就介绍到这了,更多相关SpringSecurity表单登录验证内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringSecurity 默认表单登录页展示流程源码

    SpringSecurity 默认表单登录页展示流程源码 本篇主要讲解 SpringSecurity提供的默认表单登录页 它是如何展示的的流程, 涉及 1.FilterSecurityInterceptor, 2.ExceptionTranslationFilc,xmccmc,ter , 3.DefaultLoginPageGeneratingFilter 过滤器, 并且简单介绍了 AccessDecisionManager 投票机制  1.准备工作(体验SpringSecurity默认表单认证

  • SpringSecurity 自定义表单登录的实现

    本篇主要讲解 在SpringSecurity中 如何 自定义表单登录 , SpringSecurity默认提供了一个表单登录,但是实际项目里肯定无法使用的,本篇就主要讲解如何自定义表单登录 1.创建SpringSecurity项目 1.1 使用IDEA 先通过IDEA 创建一个SpringBoot项目 并且依赖SpringSecurity,Web依赖 此时pom.xml会自动添加 <dependency> <groupId>org.springframework.boot</

  • Spring Security在标准登录表单中添加一个额外的字段

    概述 在本文中,我们将通过向标准登录表单添加额外字段来实现Spring Security的自定义身份验证方案. 我们将重点关注两种不同的方法,以展示框架的多功能性以及我们可以使用它的灵活方式. 我们的第一种方法是一个简单的解决方案,专注于重用现有的核心Spring Security实现. 我们的第二种方法是更加定制的解决方案,可能更适合高级用例. 2. Maven设置 我们将使用Spring Boot启动程序来引导我们的项目并引入所有必需的依赖项.  我们将使用的设置需要父声明,Web启动器和安

  • Spring Security 表单登录功能的实现方法

    1.简介 本文将重点介绍使用 Spring Security 登录. 本文将构建在之前简单的 Spring MVC示例 之上,因为这是设置Web应用程序和登录机制的必不可少的. 2. Maven 依赖 要将Maven依赖项添加到项目中,请参阅Spring Security with Maven 一文. 标准的 spring-security-web 和 spring-security-config 都是必需的. 3. Spring Security Java配置 我们首先创建一个扩展 WebSe

  • SpringBoot基于SpringSecurity表单登录和权限验证的示例

    一.简介 上篇介绍了一个自己做的管理系统,最近空闲的时间自己在继续做,把之前登录时候自定义的拦截器过滤器换成了基于SpringSecurity来做,其中遇到了很多坑,总结下,大家有遇到类似问题的话就当是为大家闭坑吧. 二.项目实现功能和成果展示 首先来看下登录界面:这是我输入的一个正确的信息,点击登录后SpringSecurity会根据你输入的用户名和密码去验证是否正确,如果正确的话就去你定义的页面,我这里定义的是查询教师信息页面.来看下代码吧. 三.准备工作(前台页面.实体类) 实体类Teac

  • SpringSecurity 表单登录的实现

    目录 表单登录 登录成功 登录失败 注销登录 自定义注销成功的返回内容 表单登录 @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated()

  • Vue+Express实现登录状态权限验证的示例代码

    前提 对Vue全家桶有基本的认知. 用有node环境 了解express 另外本篇只是介绍登录状态的权限验证,以及登录,注销的前后端交互.具体流程(例如:前端布局,后端密码验证等).以后有时间再对这些边边角角进行补充 一丶业务分析 1.什么情况下进行权限验证? 访问敏感接口 前端向后端敏感接口发送ajax 后端进行session验证,并返回信息 前端axios拦截返回信息,根据返回信息进行操作 进行页面切换 页面切换,触发vue-router的路由守卫 路由守卫根据跳转地址进行验证,如需权限,则

  • SpringBoot如何整合Springsecurity实现数据库登录及权限控制

    目录 第一步 第二步是封装一个自定义的类 第三步, 我们需要判断密码啦 总结 我们今天使用SpringBoot来整合SpringSecurity,来吧,不多BB 首先呢,是一个SpringBoot 项目,连接数据库,这里我使用的是mybaties.mysql, 下面是数据库的表 DROP TABLE IF EXISTS `xy_role`; CREATE TABLE `xy_role` ( `xyr_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键i

  • 基于JavaScript表单脚本(详解)

    什么是表单? 一个表单有三个基本组成部分: 表单标签:这里面包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法. 表单域:包含了文本框.密码框.隐藏域.多行文本框.复选框.单选框.下拉选择框和文件上传框等. 表单按钮:包括提交按钮.复位按钮和一般按钮:用于将数据传送到服务器上的CGI脚本或者取消输入,还可以用表单按钮来控制其他定义了处理脚本的处理工作. JavaScript与表单间的关系:JS最初的应用就是用于分担服务器处理表单的责任,打破依赖服务器的局面,尽管目前web和jav

  • 基于Ajax表单提交及后台处理简单的应用

    首先先说下表单提交吧,要提交表单那么就得先收集表单数据(至于验证这个我就不说了,要说留下下次吧),有了jquery取个html的值还是简单$("xxid").val()等就完了,但如果一张表单收集的数据很多,像这样的表单又有很多张,那用此方法肯定麻烦死,并且容易眼花录错.所以,我们就可以简单的来定义一个收集规则,如在要回传到服务器的数据表单控件,可以做个标记,到时取的时候把这些标记的数据一起取回去. 就拿最简单的文体输入做例子吧<input type="text&quo

  • 基于Bootstrap表单验证功能

    基于Bootstrap表单验证,供大家参考,具体内容如下 GitHub地址:https://github.com/chentangchun/FormValidate 使用方式: 1.CSS样式 .valierror { border-color: red !important; } .tooltip.right .tooltip-arrow { border-right-color: #d15b47; } .tooltip-inner { background-color: #d15b47; }

随机推荐