javascript
springboot整合spring security——登录管理 -凯发ag旗舰厅登录网址下载
文章目录
- 一、自定义认证成功、失败处理
- 1.1 customauthenticationsuccesshandle
- 1.2 customauthenticationfailurehandler
- 1.3 修改 websecurityconfig
- 1.4 运行程序
- 二、session 超时
- 三、限制最大登录数
- 四、踢出用户
- 五、退出登录
- 六、session 共享
- 6.1 导入依赖
- 6.3 运行程序
一、自定义认证成功、失败处理
有些时候我们想要在认证成功后做一些业务处理,例如添加积分;有些时候我们想要在认证失败后也做一些业务处理,例如记录日志。
在之前的文章中,关于认证成功、失败后的处理都是如下配置的:
http.authorizerequests()// 如果有允许匿名的url,填在下面 // .antmatchers().permitall().anyrequest().authenticated().and()// 设置登陆页.formlogin().loginpage("/login").failure.defaultsuccess.permitall()...;即 failure 指定认证失败后url,defaultsuccess 指定认证成功后url。我们可以通过设置 successhandler() 和 failurehandler() 来实现自定义认证成功、失败处理。
ps:当我们设置了这两个后,需要去除 failure 和 defaultsuccess 的设置,否则无法生效。这两套配置同时只能存在一套
1.1 customauthenticationsuccesshandle
自定义 customauthenticationsuccesshandler 类来实现 authenticationsuccesshandler 接口,用来处理认证成功后逻辑:
@component public class customauthenticationsuccesshandler implements authenticationsuccesshandler {private logger logger = loggerfactory.getlogger(getclass());@overridepublic void onauthenticationsuccess(httpservletrequest request, httpservletresponse response, authentication authentication) throws ioexception, servletexception {logger.info("登录成功,{}", authentication);response.sendredirect("/");} }onauthenticationsuccess() 方法的第三个参数 authentication 为认证后该用户的认证信息,这里打印日志后,重定向到了凯发ag旗舰厅登录网址下载首页。
1.2 customauthenticationfailurehandler
自定义 customauthenticationfailurehandler 类来实现 authenticationfailurehandler 接口,用来处理认证失败后逻辑:
@component public class customauthenticationfailurehandler implements authenticationfailurehandler {private logger logger = loggerfactory.getlogger(getclass());@autowiredprivate objectmapper objectmapper;@overridepublic void onauthenticationfailure(httpservletrequest request, httpservletresponse response, authenticationexception e) throws ioexception, servletexception {logger.info("登录失败,{}");response.setstatus(httpstatus.internal_server_error.value());response.setcontenttype("application/json;charset=utf-8");response.getwriter().write(objectmapper.writevalueasstring(e.getmessage()));} }onauthenticationfailure()方法的第三个参数 exception 为认证失败所产生的异常,这里也是简单的返回到前台。
1.3 修改 websecurityconfig
@autowiredprivate customauthenticationfailurehandler customauthenticationfailurehandler;@autowiredprivate customauthenticationsuccesshandler customauthenticationsuccesshandler; @overrideprotected void configure(httpsecurity http) throws exception {http.authorizerequests()// 如果有允许匿名的url,填在下面//.antmatchers().permitall().anyrequest().authenticated().and()// 设置登陆页.formlogin().loginpage("/login").successhandler(customauthenticationsuccesshandler).failurehandler(customauthenticationfailurehandler) // .failure // .defaultsuccess.permitall();http.csrf().disable();}1.首先将 customauthenticationsuccesshandler 和 customauthenticationfailurehandler注入进来
2.配置 successhandler() 和 failurehandler()
3.注释 failure 和 defaultsuccess
1.4 运行程序
运行程序,当我们成功登陆后,发现日志信息被打印出来,页面被重定向到了凯发ag旗舰厅登录网址下载首页:
当我们认证失败后,发现日志中“登陆失败”被打印出来,页面展示了认证失败的异常消息:
二、session 超时
当用户登录后,我们可以设置 session 的超时时间,当达到超时时间后,自动将用户退出登录。
session 超时的配置是 springboot 原生支持的,我们只需要在 application.properties 配置文件中配置:
# session 过期时间,单位:秒 server.servlet.session.timeout=60tip:
从用户最后一次操作开始计算过期时间。
过期时间最小值为 60 秒,如果你设置的值小于 60 秒,也会被更改为 60 秒。
我们可以在 spring security 中配置处理逻辑,在 session 过期退出时调用。修改 websecurityconfig 的 configure() 方法,添加:
.sessionmanagement()// 以下二选一//.invalidsessionstrategy()//.invalidsession;spring security 提供了两种处理配置,一个是 invalidsessionstrategy(),另外一个是 invalidsession。
这两个的区别就是一个是前者是在一个类中进行处理,后者是直接跳转到一个 url。简单起见,我就直接用 invalidsession了,跳转到 /login/invalid,我们需要把该 url 设置为免授权访问, 配置如下:
@overrideprotected void configure(httpsecurity http) throws exception {http.authorizerequests()// 如果有允许匿名的url,填在下面.antmatchers("/login/invalid").permitall().anyrequest().authenticated().and()// 设置登陆页.formlogin().loginpage("/login").successhandler(customauthenticationsuccesshandler).failurehandler(customauthenticationfailurehandler).permitall().and() // .failure // .defaultsuccess.sessionmanagement().invalidsession;http.csrf().disable();}在 controller 中写一个接口进行处理:
@requestmapping("/login/invalid") @responsestatus(httpstatus.unauthorized) @responsebody public string invalid() {return "session 已过期,请重新登录"; }运行程序,登陆成功后等待一分钟(或者重启服务器),刷新页面:
三、限制最大登录数
接下来实现限制最大登陆数,原理就是限制单个用户能够存在的最大 session 数。
在上一节的基础上,修改 configure() 为:
@overrideprotected void configure(httpsecurity http) throws exception {http.authorizerequests()// 如果有允许匿名的url,填在下面.antmatchers("/login/invalid").permitall().anyrequest().authenticated().and()// 设置登陆页.formlogin().loginpage("/login").successhandler(customauthenticationsuccesshandler).failurehandler(customauthenticationfailurehandler).permitall().and() // .failure // .defaultsuccess.sessionmanagement().invalidsession//指定最大登录数.maximumsessions(1)//当达到最大值时,是否保留已经登录的用户.maxsessionspreventslogin(false)//当达到最大值时,旧用户被踢出后的操作.expiredsessionstrategy(customexpiredsessionstrategy);http.csrf().disable();}增加了下面三行代码,其中:
maximumsessions(int):指定最大登录数
maxsessionspreventslogin(boolean):是否保留已经登录的用户;为true,新用户无法登录;为 false,旧用户被踢出
expiredsessionstrategy(sessioninformationexpiredstrategy):旧用户被踢出后处理方法
maxsessionspreventslogin()可能不太好理解,这里我们先设为 false,效果和 qq 登录是一样的,登陆后之前登录的账户被踢出。
编写 customexpiredsessionstrategy 类,来处理旧用户登陆失败的逻辑:
@component public class customexpiredsessionstrategy implements sessioninformationexpiredstrategy {private objectmapper objectmapper = new objectmapper();@overridepublic void onexpiredsessiondetected(sessioninformationexpiredevent event) throws ioexception, servletexception {map在 onexpiredsessiondetected() 方法中,处理相关逻辑,我这里只是简单的返回一句话。
执行程序,打开两个浏览器,登录同一个账户。因为我设置了 maximumsessions(1),也就是单个用户只能存在一个 session,因此当你刷新先登录的那个浏览器时,被提示踢出了。
下面我们来测试下 maxsessionspreventslogin(true) 时的情况,我们发现第一个浏览器登录后,第二个浏览器无法登录:
四、踢出用户
下面来看下如何主动踢出一个用户。
首先需要在容器中注入名为 sessionregistry 的 bean,这里我就简单的写在 websecurityconfig 中:
@overrideprotected void configure(httpsecurity http) throws exception {http.authorizerequests()// 如果有允许匿名的url,填在下面.antmatchers("/login/invalid").permitall().anyrequest().authenticated().and()// 设置登陆页.formlogin().loginpage("/login").successhandler(customauthenticationsuccesshandler).failurehandler(customauthenticationfailurehandler).permitall().and() // .failure // .defaultsuccess.sessionmanagement().invalidsession//指定最大登录数.maximumsessions(1)//当达到最大值时,是否保留已经登录的用户.maxsessionspreventslogin(false)//当达到最大值时,旧用户被踢出后的操作.expiredsessionstrategy(customexpiredsessionstrategy).sessionregistry(sessionregistry());http.csrf().disable();} @bean public sessionregistry sessionregistry() {return new sessionregistryimpl(); }编写一个接口用于测试踢出用户:
@getmapping("/click")@responsebodypublic string removeusersessionbyusername(@requestparam string username) {int count = 0;list