拦截器
Filter过滤器
Filter过滤器它是JavaWeb的三大组件之一。三大组件分别是: Servlet 程序、Listener 监听器、Filter 过滤器
Filter过滤器它是JavaEE的规范。也就是接口
Filter过滤器它的作用是:拦截请求,过滤响应
Filter 的工作流程图
Filter 过滤器的使用
创建一个类实现Filter接口,实现接口方法
在doFilter方法中写功能需求
到 web.xml 中去配置 Filter 的拦截路径
创建拦截器
实现Filter接口
import java.util.logging.Filter;
/**
* @author Huiex on 2021/11/8
*/
public class AdminFilter implements Filter {
//doFilter 方法,专门用于拦截请求。可以做权限检查----------
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
功能需求
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpSession session = httpServletRequest.getSession();
Object user = session.getAttribute("user");
// 如果等于 null,说明还没有登录
if (user == null) {
servletRequest.getRequestDispatcher("/login.jsp")
.forward(servletRequest,servletResponse);
return;
} else {
// 让程序继续往下访问用户的目标资源
filterChain.doFilter(servletRequest,servletResponse);
}
}
}
web.xml 中的配置
<!--filter 标签用于配置一个 Filter 过滤器-->
<filter>
<!--给 filter 起一个别名-->
<filter-name>AdminFilter</filter-name>
<!--配置 filter 的全类名-->
<filter-class>com.atguigu.filter.AdminFilter</filter-class>
</filter>
<!--filter-mapping 配置 Filter 过滤器的拦截路径-->
<filter-mapping>
<!--filter-name 表示当前的拦截路径给哪个 filter 使用-->
<filter-name>AdminFilter</filter-name>
<!--url-pattern 配置拦截路径
/ 表示请求地址为:http://ip:port/工程路径/ 映射到 IDEA 的 web 目录
/ admin/* 表示请求地址为:http://ip:port/工程路径/admin/*-->
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
Filter的生命周期
Filter 的生命周期包含几个方法
- 构造器方法
- init 初始化方法 第 1,2 步,在 web 工程启动的时候执行(Filter 已经创建)
- doFilter 过滤方法 第 3 步,每次拦截到请求,就会执行
- destroy 销毁 第 4 步,停止 web 工程的时候,就会执行(停止 web 工程,也会销毁 Filter 过滤器)
FilterChain 过滤器链
FilterChain. doFilter() 方法的作用
执行下一个Filter过滤器(如果有Filter)
执行目标资源(没有Filter)
流程图
多个Filter过滤器执行的特点
多个Filter过滤器执行的时候,它们执行的优先顺序是由 他们在web. xmI中从上到下配置的顺序决定
多个Filter共同执行的时候,它们都使用同一个Request对象
Filter 的拦截路径
精确匹配
<url-pattern>/target.jsp</url-pattern>
以上配置的路径,表示请求地址必须为:http://ip:port/工程路径/target.jsp
目录匹配
<url-pattern>/目录名/*</url-pattern>
以上配置的路径,表示请求地址必须为:http://ip:port/工程路径/admin/*
后缀名匹配
<url-pattern>>*.html</url-pattern>
以上配置的路径,表示请求地址必须以.html 结尾才会拦截到
MVC拦截器
SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能
区别
**过滤器与拦截器的区别:**拦截器是AOP思想的具体应用。
过滤器
- servlet规范中的一部分,任何java web工程都可以使用
- 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截
拦截器
- 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
- 拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的
MVC拦截器的使用
创建一个类,实现HandlerInterceptor(处理程序拦截器)
package com.kuang.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
//在请求处理的方法之前执行
//如果返回true执行下一个拦截器 相当于FiltenChain
//如果返回false就不执行下一个拦截器
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("------------处理前------------");
return true;
}
//在请求处理方法执行之后执行
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("------------处理后------------");
}
//在dispatcherServlet处理后执行,做清理工作.
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("------------清理------------");
}
}
SpringSecurity(安全)
在web开发中,需要过滤器,拦截器
Spring Security是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大
的Web安全控制,对于安全控制,我们仅需要引入spring-boot-starter-security模块,进行少量的配置,即可实
现强大的安全管理
Spring Security的两个主要目标是“认证"和"授权”(访问控制)。
“认证”(Authentication)
"授权”(Authorization)
相关类
- WebSecurityConfigurerAdapter: 自定义Security策略
- AuthenticationManagerBuilder: 自定义认证策略
- @EnableWebSecurity: 开启WebSecurity模式
依赖
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
拦截器
在config包下
SecurityConfig类
继承WebSecurityConfigurerAdapter
@EnableWebSecurity--------------
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//重写 configure(HttpSecurity http) 固定的-----------------------
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人可以访问, 功能页只有对应有权限的人才能访问--------------
http.authorizeRequests()
.antMatchers("/").permitAll()//任何人都可以访问 /下的目录
.antMatchers("/level1/**").hasRole("vip1")vip1才可以访问/level1/下的目录
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//如果没有权限 会默认自动跳转到默认登陆页面 "/login"
http.formLogin().loginPage("/login");
//注销 开启了注销功能
//默认跳转到注销页面"/logout" 加上.logoutSuccessUrl()后可以指定跳转的页面
http.logout().logoutSuccessUrl("/");
//开启记住我功能
http.rememberMe();
}
"/"所有页面所有都能访问
"/level1/**" 该页面只有"vip1"能访问(起作用)
Matchers 匹配器
permitAll 运行所有
hasRole 起作用
认证
通过从内存或者数据库中得到用户信息,通过认证得到对应的权限级别
在config包下的SecurityConfig类中
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// //这些数据正常应该从数据库中读
auth.inMemoryAuthentication()
.withUser("zjl").password("183303").roles("vip3")
.and()//and() 用来拼接 roler() 角色
.withUser("root").password("123456").roles("vip1","vip2","vip3");
}
}
//通过认证后, root这个用户可以访问vip1、2、3 , zjl用户只,能访问vip3
//一般用户的roles是在数据库中得到的,或者从内存中得到,这里没有,就直接设置了
auth.inMemoryAuthentication() 身份验证 如果是通过jdbc验证,那么用auth.jdbcAuthentication()
密码加密
不加密的话会报 500 错误
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.passwordEncoder(new BCryptPasswordEncoder())//---------
.withUser("zjl").password(new BCryptPasswordEncoder().//---------
encode("183303")).roles("vip3")
.and()
.withUser("root").password(new BCryptPasswordEncoder().
encode("123456")).roles("vip1","vip2","vip3");
}
}
shrio
依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.1</version>
</dependency>
log4j
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>