代码参考博客:java
https://blog.csdn.net/weixin_37891479/article/details/79527641web
在作学校的课设的时候,发现了安全的问题,就不怀好意的用户有可能跳过登陆直接访问系统的界面和使用里面的功能,因而想为系统加个安全验证。如今经常使用的安全框架我知道的就是Shiro还有SpringSecurity,但此次我不打算用框架,采用拦截器filter和session技术实现了一个基于session的登陆认证。spring
先简单地说一下原理:浏览器
session和cookie介绍:安全
首先要知道,session是什么。 咱们知道HTTP是个无状态的协议,在WEB开发中,服务器能够为每一个用户浏览器建立一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认状况下)。所以,在须要保存用户数据时,服务器程序能够把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序能够从用户的session中取出该用户的数据,为用户服务。 服务器
而cookie,就是把用户的数据写在浏览器,session是放在服务器的内存中的。 session和cookie都是为了跟踪与用户的会话而诞生的技术cookie
而后cookie和session的简单区别:session
session的实现原理:框架
实现思路:url
登陆成功的时候,在该浏览器用户所对应的session中,新建一个key为“hasLoginedUsersMap”,值为一个Map<String, Object> hasLoginedUsersMap的键值对,顾名思义,就是一个记录了该客户端所登录过的用户信息的Map。(为何不直接记录一个"user",User的键值对,由于考虑到一个浏览器可能用多个用户去登陆……)而后这个Map里面,每个键值对就是("userId",User),也就是键为用户id,而后值为这个User对象。 因此登陆成功后,就先看session里面有没有这个Map,若没有则创建一个并在这个Map里面添加这个userid和这个user;若是有这个Map就在这个Map中添加这个用户的userId和User信息。
每一个用户请求过来,先被Filter拦截下来,通过Filter处理后才到SpringMVC的servlet。在Filter中,看这个浏览器用户的session,看有没hasLoginedUsersMap这个Map,若是有,就说明该用户登陆过了,能够继续访问,若是没有这个Map,就重定向到别的界面,就不让他访问原来的资源。(个人主页的请求中带有用户的userId,若是是主页请求,就会去Map中看有没有这个UserId的信息,若是有就登陆过,没有的话就不让他访问。)
下面贴下代码,登陆和注销还有filter中的拦截代码就不上了,主要看看Filter的注册:
查到在Springboot中通常有两种注册这个FIlter的方法:
1.注解注册法:
在过滤器上添加WebFilter注解
在启动类添加ServletComponentScan注解:
@WebFilter(filterName = "sessionFilter",urlPatterns = {"/*"}) public class SessionFilter implements Filter {
@SpringBootApplication @ServletComponentScan public class FileUploadApplication { public static void main(String[] args) { SpringApplication.run(FileUploadApplication.class, args); } }
2.javaConfig注册:
package com.stuPayment.config; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.stuPayment.util.LoginFilter; @Configuration public class FilterConfig { @Bean public FilterRegistrationBean loginSessionFilter() {//这个类应该是Spring给咱们拿来初测filter的 FilterRegistrationBean registration = new FilterRegistrationBean();//新建过滤器的注册类 registration.setFilter(new LoginFilter());//添加咱们写好的filter registration.addUrlPatterns("/*");//设置filter的过滤的url模式 return registration;//返回这个就是Spring会帮你注入的那个对象 } }
这里提一下:
当有多个过滤器须要按顺序执行时怎么办?
使用注解的配置方法不能配置顺序,可是能够经过过滤器名字的字典顺序实现顺序过滤(好比AFilter就会在BFilter前执行),显然这种方法看起来不怎么正经。
可是咱们可使用第二种配置方法.
经过给注册类设置order,order越小,执行优先级越高
@Bean public FilterRegistrationBean someFilterRegistration1() { //新建过滤器注册类 FilterRegistrationBean registration = new FilterRegistrationBean(); // 添加咱们写好的过滤器 registration.setFilter( new SessionFilter()); // 设置过滤器的URL模式 registration.addUrlPatterns("/*"); //设置过滤器顺序 registration.setOrder(1); return registration; }