让代码同时支持两种方式,登陆访问和带着请求头的token访问也可以。
首先做代码的重构
这里改成getSession() 改成这样以后会有一个问题,我用httpBasic登陆成功以后,我的用户信息放在session里面,后续的请求不用带Authorization的请求头也能访问。
我希望实现的效果是,如果你没登陆,那么你用HttpBasic这种方式来访问,每次你的头里面都要带着这个。然后除非你登陆了,访问的时候才可以不带这个头。那么要大道这个效果的话,我们需要来分辨下,哪些session是通过httpBasic这种方式建立的session。
向下面的这个getSesison就是通过httpBasic这种方式建立的。
还有一种是调用登陆方法,在登陆方法里面创建的session
想到达的效果就是,在httpBasic这种方式创建出来的session,在他方法调用结束以后,返回的时候把这个session销毁掉。
那么下次他再上来的时候session就没了。他就必须手里带着一个token,才能再啦访问这个请求。
那么要打到这个效果,就是在这里写个try finally
把过滤器的调用放在try里面。把过滤器的调用放在try里面。然后在finally里面让他失效掉。
这么写还有个问题就是登陆的那块的session也会失效掉。所以我需要做一个判断。在httpBasic的session中多加一个temp的session。判断它不为空, 就让session失效掉。
这样我们现在即支持登陆来访问也支持httpBasic访问
用UserInfo去接收
原来在user写的方法要挪一下
把这段代码剪切到UserInfo里面
把这个属性也复制过去,注意是复制,不是剪切。
SecurityConfig
之前这里是写死的,现在我明确知道我要从session里面拿用户信息
那么Spring有一种静态的方法,可以让我们拿到session
强制转换。
从serveltRequestAttribute我们就可以拿到当前的request,再从request里拿到session
现在这个AuditorWare就可以根据真正的用户是谁,就可以拿到它的用户名来并返回。最终审计日志的时候,是当前登陆的用户名了。。
以上就重构完成了。
做退出操作
让session失效。
然后这里也改成UserInfo
运行系统
filter里面没有明显的是哪些代码是请求进来的时候调用,哪些代码是响应回去的时候调用,这样看起来不直观,不如拦截器的方法
拦截器的preHandler和afterCompletion看起来直观。
现在是没带请求头也没登陆过。所以返回的是401
带上我们的请求头
带上请求头就拿到用户信息了。
把请求头删掉依然不能访问,说明httpBasic每次请求响应回去session都被清除了。
测试登陆
登陆成功后,不带请求头访问我们的方法,因为我们是登陆过的,服务器端存了session
调用一下退出的方法
退出后,再调用getUser方法
以上就实现了我们想要的效果,我们这个方法支持两种认证方式。方法过程中有流控、身份认证、有审计、有授权等等
所有的安全机制应该都已经具备了。、