填坑,前后端分离JSON格式登录实现
写在前面如果你之前阅读过笔者写过的《前后端分离回调和注销登录》和《添加登录验证码》两篇文章,会发现一个比较尴尬的事情,当时我们说好是采用前后端分离模式,前后端之间以JOSN格式的数据进行传输,但是在用户登录的时候,我们其实并没有采用JSON格式,依旧使用了Key/Value键值对形式。除此之外,其余所有的POST请求都采用了JSON格式,这是当时笔者偷了一个懒所导致的。原因在于SpringSecurity中默认的登录数据格式就是Key/Value键值对形式,因此我就直接使用了,没做修改,但是在实际工作中有必要进行全部统一,因此本篇就来将其进行改造,使之也采用JSON格式来传输数据。
现有方式通过《详解登录流程》一文,我们知道用户登录信息是在UsernamePasswordAuthenticationFilter类中处理的,里面有三个重要的方法:
123456789101112131415161718192021222324public Authentication attemptAuthentication(HttpServletRequest request, HttpServlet ...
添加登录验证码
写在前面在前一篇《详解登录流程》一文中,笔者提到当开发者需要在SpringSecurity中自定义一个登录验证码或者将登录参数修改为JSON时,都需要自定义自己的Filter类,并继承这个AbstractAuthenticationProcessingFilter类,那么接下来的两篇就分别介绍如何自定义登录验证码和将登录参数修改为JSON格式。
本文是在之前的security-jpa项目上进行修改的。
生成验证码既然想在SpringSecurity中使用验证码,那么首先是生成验证码,这里采用Java来生成验证码。
新建一个utils包,并在里面新建一个生成验证码的工具类VerifyCode,里面的代码如下:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 ...
详解登录流程
写在前面在前面学习前后端分离模式下的回调和注销时,提到了密码擦除,当时没有对SpringSecurity的登录流程进行梳理,那么本篇就来详细学习登录流程。
场景描述现在有一个场景,用户在服务端安全管理选择了SpringSecurity,那么用户登录成功后,SpringSecurity会将用户信息保存在Session中,但是具体保存的位置,就目前而言开发者是不知道的,但是现在就是想知道这个信息的保存位置,以便当用户在前端修改了自己的信息,在不重新登录的情况下,开发者如何获取到用户的最新信息?这个场景在实际工作中是很常见的。
Authentication对象如果你之前使用过Shiro框架,那么就知道在Shiro框架中与用户认证相关的信息都在AuthenticationToken接口中,查看一下这个接口的源码:
12345public interface AuthenticationToken extends Serializable { Object getPrincipal(); Object getCredentials();}
它只有两个方法,一个获取 ...
Spring Data JPA操作数据库
写在前面在前一篇我们学习了如何基于数据库来实现授权操作,使用了JdbcUserDetailsManager类,同时发现它底层使用的是JdbcTemplate,用户操作非常不方便,且使用了JdbcUserDetailsManager自带的数据库,这些表和字段是无法满足实际的开发需要,因此通常做法是开发者自定义授权数据库和表。
出于操作简单的考虑,这里使用Spring Data JPA来代替JdbcTemplate进而完成对数据库的操作。
创建工程使用IDEA创建一个名为security-jpa的SpringBoot工程:
当然也可以在创建项目的时候不添加任何依赖,而是在后续pom.xml依赖文件中添加如下依赖:
12345678910111213141516171819202122232425262728293031323334<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
基于数据库的授权操作
写在前面前面学习的都是基于内存的授权操作,但是在实际开发过程中都是将数据存储在数据库中,因此本篇就来学习如何基于数据库来实现授权操作。
UserDetailService接口通过前面的学习,我们知道SpringSecurity存在多种认证方式,查看一下这个AuthenticationManagerBuilder类,可以发现它存在inMemoryAuthentication(内存)、jdbcAuthentication(数据库)和ldapAuthentication(LDAP)等三种认证方式:
1234567891011public InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemoryAuthentication() throws Exception { return (InMemoryUserDetailsManagerConfigurer)this.apply(new InMemoryUserDetailsManagerConfigurer());} ...
基于内存的授权操作
写在前面本篇来学习Spring Security中的授权操作,建议先阅读之前Shiro框架相关的几篇内容,通过对比学习可以加深对授权的理解。
授权授权就是当用户通过认证之后,需要访问某一资源的时候,我们需要检查用户是否具备访问该资源的权限,如果具备就允许访问;反之则不允许。
认证我们知道用户想要进行授权,前提是已经通过了认证,而SpringSecurity存在多种认证方式,查看一下这个AuthenticationManagerBuilder类,可以发现它存在inMemoryAuthentication(内存)、jdbcAuthentication(数据库)和ldapAuthentication(LDAP)等三种认证方式:
1234567891011public InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemoryAuthentication() throws Exception { return (InMemoryUserDetailsManagerConfig ...
前后端分离回调和注销登录
在前一篇学习了前后端不分离模式下的登录回调和注销登录,接下来开始学习前后端分离模式下的登录回调和注销登录。请注意,前后端分离模式下,前后端是通过json来进行数据交互,因此和之前需要采用不同的处理方式。还有前后端分离模式下认证是使用传统的session还是采用像JWT一样的token呢?这些同样需要引起注意。
状态传统方式是通过session来记录用户认证信息,可以理解为是一种无状态登录,而JWT则是一种无状态登录,那么有状态和无状态的区别是什么?在此之前需要了解http无状态以及最好知道cookie、session和token这三者之间的区别。
http无状态http协议是无状态的,这里的无状态协议是指协议对于事务处理没有记忆能力。缺少状态,说明一旦数据交换完毕,客户端与服务器之间的连接就会关闭,若想再次进行数据交换则需建立新的连接,这就意味着服务器无法从连接上跟踪会话。
会话跟踪会话,指用户登录网站后的一系列动作,如浏览商品、添加商品至购物车、购买商品等。会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie和Session,其 ...
前后端不分离回调和注销登录
写在前面按照顺序接下来应该学习登录实现的机制,但是考虑到这是入门文章,因此这里先跳过,后续再来介绍。
接下来需要针对登录成功后的两种较为普遍的场景进行介绍,其实就是前后端分离和前后端不分离这两种情况,两种情况的处理方式是不相同的,本篇介绍前后端不分离模式下的处理方式,前后端分离模式则在下篇进行介绍,同时还会学习如何注销登录。
登录成功回调SpringSecurity中有两个方法与登录成功重定向URL相关,分别是successForwardUrl和defaultSuccessUrl,那么你可能就要问了,我怎么知道这两个方法与登录成功重定向URL相关呢?
前面说过SpringSecurity中与登录相关的配置信息都在FormLoginConfigurer类中,因此回到FormLoginConfigurer和它的父类AbstractAuthenticationFilterConfigurer中,可以发现前者存在successForwardUrl方法,而后者存在defaultSuccessUrl方法。
FormLoginConfigurer#successForwardUrl方法源码如下所示: ...
自定义信息
写在前面前面使用的登录表单是Spring Security自带的,在实际开发过程中用户都会自定义登录表单、样式文件、登录接口、登录参数名称等信息,因此本篇就来研究这些内容。
自定义信息登录表单自定义SpringSecurity默认提供的登陆表单样式如下所示:
如果开发者想自定义该登陆页面及样式这也是允许的,首先用户需要在resourses文件夹下新建static目录,并在该目录中新建login.html文件,其中的代码为:
1234567891011121314151617181920212223242526272829303132333435<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>登录</title> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.5/cs ...
快速入门
在SpringBoot入门篇中曾经介绍过Spring Security的基本使用,但是考虑到实际开发过程中对于Spring Security的严苛要求,于是准备花点时间来深入研究一下SpringSecurity权限框架。
Spring Security介绍理由在介绍Spring Security之前需要介绍为什么不选择Shiro。个人觉得有三点:(1)Apache Shiro是一个轻量级的安全管理框架,提供了认证、授权、会话管理、密码管理、缓存管理等功能,而Spring Security则是一个更为复杂的安全管理框架,功能比Shiro更强大,权限控制细粒度更高,对于OAuth2的支持也更友好。(2)Spring Security源自Spring全家桶,因此与Spring框架可以做到无缝整合。(3)SpringBoot中提供了Spring Security的自动化配置方案,使得Spring Security的使用变得更加便捷。
来源其实Spring Security最早不叫Spring Security ,而是叫Acegi Security,Acegi英文意思是取消,意味着使用Acegi ...