
Web安全
文章平均质量分 90
银河架构师
微信搜索:银河架构师,发现更多精彩内容
展开
-
史上最简单的Spring Security教程(四十二):重点,也是终点,SpringSecurity工作流程图解
不知不觉间,Spring Security系列从2020年6月16日于史上最简单的Spring Security教程(一):一分钟搭建SpringSecurity开始,历时5月有余。期间断断续续的一直在写,这一段太忙,没有太多的时间,所以就一直搁置了。不过,趁着琐碎的时间间隙,也思考了下这个系列的终结篇写什么内容。既然是终结篇,那就总结一下 Spring Security 框架的工作流程,算是为此系列暂时画上一个句号。其实,Spring Security 框架最厉害、最核心的,就是过滤器链...原创 2020-11-25 14:56:26 · 2851 阅读 · 5 评论 -
史上最简单的Spring Security教程(四十一):SecurityContextHolder及SecurityContextHolderStrategy详解
如何静态的、较为方便的获取当前系统已登录的用户的信息?这恐怕就要靠 Spring Security 框架的另外一个“著名”的组件类SecurityContextHolder了。/** * Associates a given {@link SecurityContext} with the current execution thread. */SecurityContextHolder类最核心的作用,便是将当前给定的 SecurityContext 与 当前执行线程绑定,从而方便...原创 2020-11-25 14:53:54 · 6639 阅读 · 3 评论 -
史上最简单的Spring Security教程(四十):SecurityContextPersistenceFilter详解
SecurityContextPersistenceFilter,为Spring Security框架Filter Chain过滤器链的第一个 Filter,具有不可或缺的作用。/** * Populates the {@link SecurityContextHolder} with information obtained from the * configured {@link SecurityContextRepository} prior to the request an...原创 2020-11-11 10:36:17 · 2476 阅读 · 0 评论 -
史上最简单的Spring Security教程(三十九):ExceptionTranslationFilter自动化配置及其简介
前面我们讲了Spring Security框架中承载着承上启下的作用的 Filter:ExceptionTranslationFilter。其中,当后续 Filter 发生 AuthenticationException 异常,或者是 AccessDeniedException 异常且此时为未登录状态或者是记住我状态,则调用 AuthenticationEntryPoint 来处理。一般情况下,如无特殊需求,我们不会对 Spring Security 的异常处理做什么配置,那么系统又是如何自动...原创 2020-10-31 09:40:00 · 1676 阅读 · 1 评论 -
史上最简单的Spring Security教程(三十八):ExceptionTranslationFilter详解
这是Spring Security框架FilterChain中倒数第二个 Filter,承载着承上启下的作用。还记得 FilterSecurityInterceptor 吗?史上最简单的Spring Security教程(十六):FilterSecurityInterceptor详解。如当用户未登录时抛出的 AccessDeniedException 异常、或者其它 AuthenticationException 异常。此时,系统会跳转到固定的页面,如 403 页面、或者执行其它操作。...原创 2020-10-24 09:20:27 · 1509 阅读 · 1 评论 -
史上最简单的Spring Security教程(三十七):RememberMe记住我原理剖析
用户登录中常用的RememberMe-记住我功能,通俗来讲,即用户成功登录一次以后,系统自动记住该用户一段时间(可配置,Spring Security 框架默认为两周)。而在此时间段内,用户不必重新登录即可访问系统资源。本文即对Spring Security框架提供的RememberMe-记住我实现逻辑进行详细讲解,剖析其实现过程。用户登录首先,在用户登录时,如果用户勾选了 记住我 选项,则系统会将该用户的一些信息进行处理,以便下次不必登录即可访问系统。在第一次登录时,请求会由 Us...原创 2020-10-20 19:06:56 · 1783 阅读 · 0 评论 -
史上最简单的Spring Security教程(三十六):RememberMeAuthenticationFilter详解
前面我们讲了记住我登录方式,以及和其它登录方式相融合的多种登录形式,想必对记住我登录方式有了一个大致清晰的了解。本次我们就来说一下其中一个比较重要的Filter,即RememberMeAuthenticationFilter。RememberMeAuthenticationFilter是记住我登录方式比较重要的类,其主要功能有自动登录、身份认证、登录成功、事件发布、异常处理/登录失败等。另外,重要的一点是,该 Filter 执行有一个条件,就是当前用户尚未认证。if...原创 2020-10-19 20:15:48 · 1431 阅读 · 0 评论 -
史上最简单的Spring Security教程(三十五):RememberMe记住我之更安全的实现方式-持久化token存储方式PersistentTokenBasedRememberMeServic
前面介绍的几种RememberMe实现方式,全部都是基于RememberMeServices接口的实现TokenBasedRememberMeServices。此实现是将username、过期时间、password、key等按照一定的规则组合之后取MD5值,之后将此值存在浏览器的Cookie中。大部分网站的RememberMe 实现方式都是基于此。但是,将用户的 password 存储在浏览器的 Cookie 中, 始终存在隐患,即使难以实现。因此,Spring Security 框架...原创 2020-10-15 15:55:38 · 1535 阅读 · 1 评论 -
史上最简单的Spring Security教程(三十四):用户名密码验证码(记住我)登录与CA登录融合方案
在上一篇文章史上最简单的Spring Security教程(三十三):用户名密码登录新增验证码和RememberMe(记住我)选项中,介绍了如何基于Spring Security框架默认的用户名密码登录,自定义 Filter 且添加 验证码、记住我 选项。如前面文章所述,一个系统的登录方式不止一种,本文即介绍一下如何基于Spring Security框架默认的用户名密码登录,自定义 Filter 且添加 验证码、记住我 选项。废话不多说,直接看配置。首先,改造一下登录页,在此前的基...原创 2020-10-15 15:53:45 · 1190 阅读 · 0 评论 -
史上最简单的Spring Security教程(三十三):用户名密码登录新增验证码和RememberMe(记住我)选项
前面我们讲了如何基于Spring Security框架默认的用户名密码登录方式,为其添加RememberMe(记住我)选项。另外,也讲过如何基于Spring Security框架默认的用户名密码登录方式,添加验证码选项。本文即同样基于Spring Security框架默认的用户名密码登录方式,同时添加RememberMe(记住我)、验证码选项。首先,改造登录页,新增记住我、验证码选项。<form th:action="@{/login}" method="pos...原创 2020-10-10 22:57:45 · 1102 阅读 · 0 评论 -
史上最简单的Spring Security教程(三十二):默认用户名密码记住我登录与CA登录融合方案
在上一篇文章史上最简单的史上最简单的Spring Security教程(三十一):默认用户名密码登录新增RememberMe(记住我)选项中,介绍了如何基于 Spring Security 框架默认的用户名密码登录,添加 记住我 选项。如前面文章所述,一个系统的登录方式不止一种,本文即介绍一下如何基于 Spring Security 框架默认的用户名密码登录,添加 记住我 选项后,与CA登录方式共存。废话不多说,直接看配置。首先,改造一下登录页,在此前的基础上,新增CA登录方式。&l...原创 2020-10-10 22:55:47 · 1028 阅读 · 0 评论 -
史上最简单的Spring Security教程(三十一):默认用户名密码登录新增RememberMe(记住我)选项
在我们登录一些网站的时候,通常会有一个选项-记住我。选中该选项,登录成功后,无论浏览器关闭,还是服务重启,只要不清除浏览器缓存信息,且Cookie在网站预设的有效期时间内,则无需重新登录网站即可访问其资源。其实,Spring Security框架也可以实现相同的功能。本文便基于Spring Security框架默认的用户名密码登录为基础,为其添加RememberMe(记住我)选项。首先,修改登录页面,将 记住我 复选框name属性修改为remember-me。<for...原创 2020-09-27 16:25:59 · 1472 阅读 · 0 评论 -
史上最简单的Spring Security教程(三十):自定义用户名密码及验证码登录与CA登录方式共存详细实现及配置
前面我们讲了CA登录方式的详细实现及配置,也讲了如何改造默认的用户名密码登录方式,添加验证码登录选项。本次,我们就将这两种方式融合在一起,实现共存,以达到用户可以自由选择验证码登录、CA登录方式。其实,重要的逻辑在前面的文章中都以实现过,本次只需合并相应逻辑到一起即可。然后,修改 Spring Security 配置,以实现两种登录方式的共存。@EnableWebSecurity@Configurationpublic class SpringSecurityConfiguration ...原创 2020-09-27 16:24:00 · 1257 阅读 · 0 评论 -
史上最简单的Spring Security教程(二十九):用户名密码登录添加验证码选项
在系统登录中,为了防止恶意攻击,通常都会采用验证码登录方式。不过,随着科技的进度,验证码也容易被人破解,那么也就催生除了更为高级的验证方式,如指定图片内容选择、人机交互等复杂的验证方式。不过,这些都不是本次我们要讨论的对象,本次我们只针对普通的验证码方式,来对用户名密码登录方式进行改造。添加依赖首先,我们添加一下本次改造需要使用的第三方依赖,即 hutool 工具包。<dependency> <groupId>cn.hutool</grou.原创 2020-09-21 11:45:03 · 2000 阅读 · 2 评论 -
史上最简单的Spring Security教程(二十八):CA登录与默认用户名密码登录共存详细实现及配置
在前面的文章中,我们自定义了一些CA登录相关的类,如CertificateAuthorityAuthenticationToken、CertificateAuthorityAuthenticationFilter、CertificateAuthorityDaoAuthenticationProvider等。但是,由于诸多条件的不具备,也就没有办法演示。不过,目前一个新登录方式所需要的逻辑基本都介绍过了,下面,就利用这些已经自定义的类,来尝试如何自定义个新的登录方式-CA登录。并且,CA登录需要与默认.原创 2020-09-20 14:44:31 · 3495 阅读 · 1 评论 -
史上最简单的Spring Security教程(二十七):AuthenticationManager默认实现之ProviderManager详解
Spring Security 框架中的另一个重要接口AuthenticationManager, 被设计用于处理Authentication请求。与AuthenticationProvider接口一致,AuthenticationManager接口中有且只有一个方法,即authenticate(Authentication authentication)方法。Authentication authenticate(Authentication authentication)...原创 2020-09-17 15:35:33 · 3535 阅读 · 0 评论 -
史上最简单的Spring Security教程(二十五):UsernamePasswordAuthenFilter详解
在Spring Security框架中,最常用的 Filter 便是表单登录Filter,即 UsernamePasswordAuthenticationFilter。下面我们就来一起详细了解一下这个 Filter 的具体功用。首先,既然是Filter,势必要实现 Filter 接口吧,不过,确实实现了 Filter 接口。从上图中,能清晰的了解到 UsernamePasswordAuthenticationFilter 的继承关系,也确实实现了 Filter 接口。那么,我们便从..原创 2020-08-28 15:12:40 · 3872 阅读 · 0 评论 -
史上最简单的Spring Security教程(二十六):DaoAuthenticationProvider详解
之前看过很多个版本的Spring Security中获取用户信息并进行密码校验,有在相关的Filter中获取的,也有在默认的DaoAuthenticationProvider中判断Authentication类型进行判断以后直接获取的。不过,这些方式都不太“正宗”,Spring Security有自己的一套流程。至于此流程的详细信息讲解,先不急,本篇文章来认识一下其中比较重要的一环:获取用户信息并进行密码验证,即DaoAuthenticationProvider。Auth...原创 2020-08-28 15:04:16 · 13835 阅读 · 3 评论 -
史上最简单的Spring Security教程(二十四):自定义用户名密码参数名及用户名密码验证路径
无论是表单登录配置器(FormLoginConfigurer),还是用户密码验证Filter(UsernamePasswordAuthenticationFilter),Spring Security默认的用户名、密码参数名均为username、password。表单登录配置:public FormLoginConfigurer() { super(new UsernamePasswordAuthenticationFilter(), null); usernamePa...原创 2020-08-24 10:25:37 · 2814 阅读 · 0 评论 -
史上最简单的Spring Security教程(二十三):自定义AccessDecisionManager实现类选举法的访问决策
前面讲过Spring Security框架实现的一个AccessDecisionManager,是少数服从多数的授权访问决策。但是,在具体业务场景中,可能还会遇到类似于选举法的授权场景,即少数服从多数且超过半数同意。那么,本次便参考此授权决策方案,自定义一个AccessDecisionManager。由于核心授权逻辑还是少数服从多数,所以我们部分参考一下ConsensusBased的授权决策逻辑。public void decide(Authentication authent...原创 2020-08-24 10:17:30 · 1622 阅读 · 0 评论 -
史上最简单的Spring Security教程(二十二):自定义AccessDecisionManager实现简单的访问决策
在前面讲过的资源权限动态控制业务场景中,我们使用了 Spring Security 框架默认的 AccessDecisionManager,即AffirmativeBased。能实现的访问决策即为任一AccessDecisionVoter授予权限,即代表授予访问权限。但是我们只添加了一个AccessDecisionVoter,即RoleVoter。既然如此,我们就可以简化一下这些逻辑,直接自定义一个新的 AccessDecisionManager,其决策逻辑为:当前请求所需的所有 ...原创 2020-08-19 13:52:32 · 2069 阅读 · 0 评论 -
史上最简单的Spring Security教程(二十一):AccessDecisionManager简介及自定义访问决策管理器
AccessDecisionManager顾名思义,访问决策管理器。Makesafinalaccesscontrol(authorization)decision做出最终的访问控制(授权)决定。而常用的AccessDecisionManager有三个,分别介绍一下其权限决策逻辑。AffirmativeBasedSpring Security框架默认的AccessDecisionManager。/** * Simple concrete ...原创 2020-08-10 09:04:03 · 12545 阅读 · 5 评论 -
史上最简单的Spring Security教程(二十):自定义AccessDecisionVoter实现必须全部拥有请求所需权限才可访问的需求
前面我们说了AccessDecisionVoter的一些基本用法,以及常用的一些AccessDecisionVoter实现,当然,也试着自定义了一个AccessDecisionVoter。细心的同学可能有所发现,这个自定义的AccessDecisionVoter不寻常。为什么呢?因为它内部的授权决策逻辑刚好就是必须拥有当前请求所需的全部权限才会授权成功。同时,这也是这次我们要着重说的内容。public int vote(Authentication authenticatio...原创 2020-08-07 14:21:34 · 1510 阅读 · 0 评论 -
史上最简单的Spring Security教程(十九):AccessDecisionVoter简介及自定义访问权限投票器
为了后续对AccessDecisionManager的介绍,我们先来提前对AccessDecisionVoter做个简单的了解,然后,在捎带手自定义一个AccessDecisionVoter。AccessDecisionVoter的注释介绍如下:Indicatesaclassisresponsibleforvotingonauthorizationdecisions. Thecoordinationofvoting(iepolling{@codeA...原创 2020-08-07 14:19:57 · 4327 阅读 · 2 评论 -
史上最简单的Spring Security教程(十八):FilterSecurityInterceptor实现每个请求只处理一次
在前面的资源权限动态控制中,我们说了如何通过自定义 FilterSecurityInterceptor 来实现资源权限的动态控制。不知道大家发现没有,在 FilterSecurityInterceptor 实例的定义过程中,我们设置了其 observeOncePerRequest 属性为 false。这是出于什么目的呢?其实,很简单。比如用户发起某个访问请求,首先经过默认的 FilterSecurityInterceptor,经过权限检查,需要身份认证权限,此时已经登录,权限认证通过;再交给自定义...原创 2020-08-05 09:22:25 · 2160 阅读 · 3 评论 -
史上最简单的Spring Security教程(十七):FilterSecurityInterceptor默认初始化逻辑剖析
Spring Security框架默认会自动创建一个FilterSecurityInterceptor实例,如我们前面所述,自定义的FilterSecurityInterceptor要么是在默认FilterSecurityInterceptor实例之前,要么是在之后,看具体业务场景。为啥我们不能替换掉默认的FilterSecurityInterceptor实例呢?先来剖析一下默认的FilterSecurityInterceptor实例初始化逻辑。SecurityMeta...原创 2020-08-05 09:19:22 · 4082 阅读 · 0 评论 -
史上最简单的Spring Security教程(十六):FilterSecurityInterceptor详解
FilterSecurityInterceptor作为Spring Security Filter Chain的最后一个Filter,承担着非常重要的作用。如获取当前 request 对应的权限配置,调用访问控制器进行鉴权操作等,都是核心功能。先简单看一下FilterSecurityInterceptor类的主要功用。获取当前 request 对应的权限配置,首先是调用基类的beforeInvocation方法。public void invoke(FilterInv...原创 2020-07-29 13:46:34 · 9478 阅读 · 5 评论 -
史上最简单的Spring Security教程(十五):资源权限动态控制(FilterSecurityInterceptor)
在前面的讲解中,我们分别对动态用户、动态权限的实现做了相关介绍。可能大家在看的过程中,会发现一个问题:目前都是通过注解控制权限的,并且角色是事先定义好的,且需要数据库、Java程序保持一致。这是非常不友好的,不能自由的定义角色及其所能控制的资源。角色比较少且固定的业务场景还好,如OA,只有管理员和普通用户两种角色。但是遇到大型业务系统,角色细且繁多,需要自定义,且需要频繁变更其所拥有的资源,那么,目前的形式就显得非常笨拙。接下来,就如何进行资源权限动态控制进行讲解,要实现的目标为:Java程序...原创 2020-07-27 10:26:36 · 3682 阅读 · 9 评论 -
史上最简单的Spring Security教程(十四):动态权限(自定义UserDetailsService)
在前面的示例中,我们在自定义的UserDetailsService中,固化了用户所拥有的的权限,即User。其实,这和最早我们在配置文件配置用户的用户名、密码、权限列表并无二致,这种固化的方法尤其独到之处,但却并不适合所有业务场景。本例,我们来说一下如何实现动态权限。首先,定义角色表、角色用户关联表。create table SYS_ROLE( ID varchar(32) not null comment '主键', NAME...原创 2020-07-27 10:23:43 · 3824 阅读 · 0 评论 -
史上最简单的Spring Security教程:终极篇,注意,这不是终点,不是最后一篇!!!
说起来Web应用安全,通用的方案无非 Spring Security 和 Apache Shiro。这两者我们在此不做比较,用Spring Security多,无非是因为 Spring 框架的“裙带关系”,当然了,也有一些其它原因,如CAS集成、OAuth2集成等等,都有比较成熟的集成框架方案。Spring Security框架,说实话,比较复杂,好多人一开始不太理解,只会照搬网上的答案,遇到问题解决不了。这是非常不好的习惯,技术方案一定是自己能解决的,或者说比较容易找到解决方案的,不然生产环境出问题、原创 2020-07-23 15:46:28 · 5050 阅读 · 4 评论 -
史上最简单的Spring Security教程(十三):动态用户(自定义UserDetailsService)
前面我们讲过的例子,都是在配置文件中配置的用户信息,包括用户名、密码、角色等,而这些,会被初始化到InMemoryUserDetailsManager中,即存储在内存中。但是,在实际的业务场景中,不可能只有一个用户,更不可能用户信息都是固定的,而是动态的,需要从存储的地方获取,如数据库。首先,我们把用户信息存储在数据库中,创建数据库springsecuritylearning,编码方式utf8mb4,排序规则utf8mb4_bin。然后定义用户表SYS_USER。crea...原创 2020-07-23 15:12:40 · 4205 阅读 · 0 评论 -
史上最简单的Spring Security教程(十二):@PreAuthorize注解实现权限控制
我们前面讲的所有的例子,都是没有权限控制的,也就是只要登录就可以访问任何资源,不需要其它的权限。但是,现实生活中肯定不是这样。比如你是普通员工,只能查看自己的工作记录;而部门经理作为领导,则可以查看整个部门员工的工作记录;再如企业老板,作为最大的权限拥有者,可以查看整个公司员工的工作记录。这就是所谓的权限控制,不同角色拥有的不同资源。而Spring Security框架最大的功用就在于此。当然,实现权限控制体系非常复杂,我们一步一步来,本次先讲一个如何通过注解实现权限控制需求。Spri...原创 2020-07-17 17:11:11 · 32654 阅读 · 7 评论 -
史上最简单的Spring Security教程(十一):url区分不同的登录失败场景
前面我们自定义了登录失败页面,其中有简单的登录失败原因的展示。不过,有更为特殊的业务场景,需要从url中区分不同的用户登录失败场景,以方便其它关联操作。如用户名密码错误/login_fail?error=1,账号锁定/login_fail?error=2等。先定义几种常见的登录失败类型。FAILURE(0, "登录失败!"),BADCREDENTIALS(1, "用户名密码错误!"),LOCKED(2, "用户已被锁定,无法登录!"),ACCOUNTEXPIRED(3, "..原创 2020-07-15 16:09:30 · 2556 阅读 · 2 评论 -
史上最简单的Spring Security教程(十):AuthenticationFailureHandler高级用法
在前面,我们简述了如何自定义用户登录失败页面。但是,在工作中,所遇到的业务场景压根不会这么简单。比如要求记录登录失败时的IP、时间、SessionId;发送登录失败提醒到微信、邮箱、短信,提醒用户当前登录失败事件;同时记录到日志中,或者发送到远端日志监控平台,分析是否是攻击行为等等。而这一切,Spring Security框架非常贴心的提供了AuthenticationFailureHandler接口,当然了,框架同时也提供了一些简单的实现,最重要的,用户可自行扩展,以满足不同的业务场景...原创 2020-07-07 15:09:56 · 12706 阅读 · 7 评论 -
史上最简单的Spring Security教程(九):自定义用户登录失败页面
生活中肯定存在这样的场景,在登录某个网站时,难免会忘记密码,或是验证码输入错误,造成多次尝试。所以,有必要适度的提醒用户,到底是什么原因造成了登录失败,如用户名密码不正确、验证码错误等等。由于Spring Security框架自带的登录失败url为/login?error,除了知道是登录失败了,其它的,可以说是毫无用处。所以,需要我们自定义用户登录失败页面。先来做一个简单的登录失败页面,简单的展示一下失败信息。......<div class="col-sm-12 ...原创 2020-07-03 16:04:11 · 3108 阅读 · 0 评论 -
史上最简单的Spring Security教程(八):用户登出成功LogoutSuccessHandler高级用法
大多数业务场景下,自定义登出成功页面也满足不了一些要求,更别提默认的登出成功页面。这时候,就需要别的方案支持,幸运的是,Spring Security框架还真就非常贴心的提供了这样一个接口LogoutSuccessHandler, 专门用于处理用户登出成功请求。当然了,对于LogoutSuccessHandler接口,Spring Security框架有一些默认的实现,也可以自行扩展。同用户登录成功的业务场景,在用户登出成功后,我们也要通过邮件、短信、微信,来通知用户,在什么时间,什么...原创 2020-07-01 11:16:32 · 12792 阅读 · 6 评论 -
史上最简单的Spring Security教程(七):用户登出成功url配置
Spring Security框架默认的用户登出成功url为/login?logout,大多数情况下,由于种种原因,这都不满足我们的业务场景,都需要自定义。Spring Security框架自定义用户登出成功url也比较简单。http.logout().logoutSuccessUrl("/logout_success").permitAll()这里的permitAll()非常重要,还记得之前Spring Security框架默认的用户登出成功url为/login?log...原创 2020-07-01 11:14:30 · 2770 阅读 · 2 评论 -
史上最简单的Spring Security教程(六):用户登出
既然有用户登录,势必就会有用户登出,Spring Security也提供了比较详细的登出配置。其实,之前的程序中,依然支持用户登出,不知道有人点过退出登录按钮没有,结果是404。其实,原因也很简单,我们的退出登录按钮使用超链接实现的,而超链接是 GET 方式请求的,在Spring Security用户登出配置中,CSRF默认是开启的,并没有关闭,不支持 GET 类型的用户登出请求。因此,就会抛出404的错误码。...... if (http.getConfigurer(...原创 2020-07-01 11:12:37 · 3875 阅读 · 1 评论 -
因为一句代码,老大差点拿我祭旗!Spring Security authorizeRequests 顺序问题不容忽视
今天,老大给我布置了一个非常简单的任务,真的非常简单:开发一个个人基本信息展示页面,展示个人的一些基本信息,并且权限配置要配置为无需登录即可访问。感谢大哥照顾我,给我这么简单的任务,那就开干吧。一顿操作猛如虎,页面写完后,到Spring Security的配置方面,不就是无权限认证嘛,还不是手到擒来。http..authorizeRequests().antMatchers("/user/profile/**").permitAll()这么简单的东西,没有必要再走各种测试流程...原创 2020-06-25 18:40:56 · 6337 阅读 · 3 评论 -
史上最简单的Spring Security教程(五):成功登录SuccessHandler高级用法
在了解了如何简单的配置成功登录后调转的页面、如何始终指定系统跳转到某一地址后,我们可能会庆幸,原来如此简单。是的,确实如此简单,Spring Security框架协助我们完成了大部分的工作,而我们只需稍微配置,即可使用。但是,业务场景,又何尝会如此简单。举个例子,我们在登录某个网站之后,微信、短信、邮箱可能会接受到一条这样的信息/邮件。还有,比如这样的。甚至于,我要记录每一次的登录信息到数据库、到日志文件等等,方便后续做审计、分析。其实,Spring Security框架也...原创 2020-06-25 18:39:18 · 8145 阅读 · 0 评论