权限校验过滤器

-------------------siwuxie095

使用过滤器进行权限校验

一个简单的权限校验过滤器实例:

登录状态校验:如果没有成功登录就没有权限访问特定页面

当访问首页要进入
hello.jsp 页面时,首先判断是否处于登录状态:

(1)如果是,直接点击进入
hello.jsp

(2)如果否,则点击 hello.jsp 时进入 login.jsp,登录成功后自动跳转回 hello.jsp

工程结构目录如下:

后端代码:

LoginServlet.java:


package com.siwuxie095.servlet;

import java.io.IOException;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

// LoginServlet 继承自 HttpServlet

public class LoginServlet extends HttpServlet {

/**

* 用于序列化和反序列化的 ID

*/

private static final
long serialVersionUID = -7740192486028671728L;

//覆盖父类 HttpServlet 的 doGet() 方法

@Override

protected
void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

System.out.println("===== doGet =====");

//在 doGet() 方法里调用 doPost() 方法

//这样,GET请求和POST请求可以共用一套处理逻辑

doPost(req, resp);

}

//覆盖父类 HttpServlet 的 doPost() 方法

@Override

protected
void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

System.out.println("===== doPost =====");

String userName=req.getParameter("uname");

String password=req.getParameter("upwd");

/**

* returnUri是用户访问登录页面之前所访问的页面

* 通过这个值,登录成功后,可以跳转回登录前的页面

*/

String returnUri=req.getParameter("return_uri");

System.out.println("用户名:"+userName);

System.out.println("密码:"+password);

System.out.println("return uri:"+returnUri);

String forward=null;

if (userName.equals("李白")&&password.equals("8888")) {

//如果用户登录成功,就在当前用户的session对象中

//保存key为flag,value为login_success的字符串

//表明当前用户处于登录状态

req.getSession().setAttribute("flag", "login_success");

//如果returnUri不为空,就进入用户访问登录页面之前所访问的页面

if (returnUri!=null) {

forward=returnUri;

}else{

forward="/index.jsp";

}

}else {

req.getSession().setAttribute("flag", "login_error");

req.setAttribute("msg", "用户名或密码错误!!!");

forward="/login.jsp";

}

RequestDispatcher rd=req.getRequestDispatcher(forward);

rd.forward(req, resp);

}

}

LogoutServlet.java:


package com.siwuxie095.servlet;

import java.io.IOException;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class LogoutServlet extends HttpServlet {

private static final
long serialVersionUID = 1L;

public LogoutServlet() {

super();

}

protected
void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

doPost(req, resp);

}

protected
void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//退出逻辑,直接删除session对象

req.getSession().invalidate();

//跳转回首页

resp.sendRedirect(req.getContextPath()+"/index.jsp");

}

}

EncodingFilter.java:


package com.siwuxie095.filter;

import java.io.IOException;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

public class EncodingFilter implements Filter {

//声明一个成员变量
用来保存当前应用的字符集名称

private String charEncoding=null;

public EncodingFilter() {

}

public
void init(FilterConfig fConfig) throws ServletException {

//在部署描述符中设置该应用的默认字符编码集
在init方法中获取到该设置

charEncoding=fConfig.getInitParameter("encoding");

//如果字符编码的名称没有设置
就抛出一个异常

if (charEncoding==null) {

throw new ServletException("EncodingFilter中的编码设置为空!!!");

}

}

public
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

//如果当前应用的默认编码,与请求中的编码值不一致

if (!charEncoding.equals(request.getCharacterEncoding())) {

//那么就将请求中的编码设置成当前默认的编码设置

request.setCharacterEncoding(charEncoding);

}

//将响应的编码设置也改成当前默认的编码设置

response.setCharacterEncoding(charEncoding);

chain.doFilter(request, response);

}

public
void destroy() {

}

}

PermissionFilter.java:


package com.siwuxie095.filter;

import java.io.IOException;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

public class PermissionFilter implements Filter {

public PermissionFilter() {

}

public
void init(FilterConfig fConfig) throws ServletException {

}

public
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

throws IOException, ServletException {

/**

* 首先将参数中的ServletRequest和ServletResponse强制转换为

* HttpServletRequest和HttpServletResponse

*/

HttpServletRequest req = (HttpServletRequest) request;

HttpServletResponse resp = (HttpServletResponse) response;

// 获取请求中的ServletPath,即servlet的路径

String servletPath = req.getServletPath();

// 获取session对象

HttpSession session = req.getSession();

// 获取session对象中的flag值,需强转

String flag = (String) session.getAttribute("flag");

// 如果用户访问的是首页index.jsp 或者是login.jsp

//或者执行登录操作
那么就将请求转发给下一个组件进行处理

if (servletPath != null && (servletPath.equals("/login.jsp") || (servletPath.equals("/index.jsp"))

|| (servletPath.equals("/loginServlet")))) {

chain.doFilter(request, response);

} else {

/**

* 业务逻辑:
对于请求的其他url都会进行权限校验

*

* 如果用户处于登录状态
可以直接进行访问

*/

if (flag != null && flag.equals("login_success")) {

chain.doFilter(request, response);

} else if (flag != null && flag.equals("login_error")) {

/**

* 如果用户登录失败
返回login.jsp

* 同时提示用户,登录失败

*/

req.setAttribute("msg", "登录失败,请重新登录!!!<br/>");

// 把用户所访问的url保存到request对象中

req.setAttribute("return_uri", servletPath);

RequestDispatcher rd = req.getRequestDispatcher("/login.jsp");

rd.forward(req, resp);

} else {

// 如果用户没有登录
同样也返回login.jsp 提示尚未登录

req.setAttribute("msg", "您尚为登录!!!");

// 同样将用户访问的url保存到request对象中

req.setAttribute("return_uri", servletPath);

RequestDispatcher rd = req.getRequestDispatcher("/login.jsp");

rd.forward(req, resp);

}

}

}

public
void destroy() {

}

}

前端代码:

login.jsp:


<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta
http-equiv="Content-Type"
content="text/html; charset=UTF-8">

<title>登录页面</title>

<script
type="text/javascript">

function check(form){

if(document.forms.loginForm.uname.value==""){

alert("请输入用户名!");

document.forms.loginForm.uname.focus();

return false;

}

if(document.forms.loginForm.upwd.value==""){

alert("请输入密码!");

document.forms.loginForm.upwd.focus();

return false;

}

}

</script>

<style type="text/css">

body {

color: #000; font-size =14px;

margin: 20px, auto;

}

</style>

</head>

<body>

<!-- 添加表单,url在部署描述符中进行配置,使用post方式来提交 -->

<form
action="<%= request.getContextPath() %>/loginServlet"
method="post"
name="loginForm">

<!-- 添加一个隐藏域,用于保存returnUri -->

<%
if(request.getAttribute("return_uri")!=null){ %>

<input
type="hidden"
name="return_uri"
value="<%= request.getAttribute("return_uri") %>"
/>

<% } %>

<table
border="1"
cellspacing="0"
cellpadding="5"
bordercolor="silver"
align="center">

<tr>

<td
colspan="2"
align="center"
bgcolor="#E8E8E8">用户登录</td>

</tr>

<tr>

<td>用户名:</td>

<td><input
type="text"
name="uname"
/></td>

</tr>

<tr>

<td>密码:</td>

<td><input
type="password"
name="upwd"
/></td>

</tr>

<tr>

<td
colspan="2"
align="center">

<input
type="submit"
name="submit"
onclick="return check(this);"
/>

<input
type="reset"
name="reset"
/>

</td>

</tr>

</table>

</form>

</body>

</html>

index.jsp:


<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta
http-equiv="Content-Type"
content="text/html; charset=UTF-8">

<title>首页</title>

</head>

<body>

首页<br/><br/>

<a
href="<%=request.getContextPath() %>/hello.jsp">hello.jsp</a><br/>

<%-- 从 session 中获取用户的登录状态 --%>

<%

String flag = "";

Object obj=session.getAttribute("flag");

if(obj!=null){

flag=obj.toString();

}

if(flag.equals("login_success")){

%>

<a
href="<%= request.getContextPath() %>/logoutServlet">退出</a>

<% }else{ %>

<a
href="<%= request.getContextPath() %>/login.jsp">登录</a>

<% } %>

</body>

</html>

hello.jsp:


<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta
http-equiv="Content-Type"
content="text/html; charset=UTF-8">

<title>Hello World</title>

</head>

<body>

<%

out.print("Hello World<br/>");

%>

<a
href="<%= request.getContextPath() %>/index.jsp">首页</a>

</body>

</html>

在部署描述符
web.xml 中注册 servlet 和 filter:


<?xml
version="1.0"
encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">

<display-name>MyFilter</display-name>

<welcome-file-list>

<welcome-file>index.html</welcome-file>

<welcome-file>index.htm</welcome-file>

<welcome-file>index.jsp</welcome-file>

<welcome-file>default.html</welcome-file>

<welcome-file>default.htm</welcome-file>

<welcome-file>default.jsp</welcome-file>

</welcome-file-list>

<servlet>

<servlet-name>LoginServlet</servlet-name>

<servlet-class>com.siwuxie095.servlet.LoginServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>LoginServlet</servlet-name>

<url-pattern>/loginServlet</url-pattern>

</servlet-mapping>

<servlet>

<servlet-name>LogoutServlet</servlet-name>

<servlet-class>com.siwuxie095.servlet.LogoutServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>LogoutServlet</servlet-name>

<url-pattern>/logoutServlet</url-pattern>

</servlet-mapping>

<filter>

<filter-name>EncodingFilter</filter-name>

<filter-class>com.siwuxie095.filter.EncodingFilter</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>UTF-8</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>EncodingFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<filter>

<filter-name>PermissionFilter</filter-name>

<filter-class>com.siwuxie095.filter.PermissionFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>PermissionFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

</web-app>

部署描述符
web.xml 在 WEB-INF 目录下,如果没有,手动创建即可

选择工程
MyFilter,右键->Java EE Tools->Generate Deployment Descriptor Stub

访问:localhost:8080/MyFilter/index.jsp

点击 hello.jsp,跳转到:localhost:8080/MyFilter/hello.jsp,

分别输入
李白
和 8888

登录成功,跳转回
hello.jsp 页面的内容

点击
首页,此时
index.jsp 页面的内容

【made by siwuxie095】

时间: 2024-12-22 13:23:54

权限校验过滤器的相关文章

SpringCloud(8)----zuul权限校验、接口限流

项目代码GitHub地址:https://github.com/yudiandemingzi/spring-cloud-study 一.权限校验搭建 正常项目开发时,权限校验可以考虑JWT和springSecurity结合进行权限校验,这个后期会总结,这里做个基于ZuulFilter过滤器进行一个简单的权限校验过滤. 对于组件zuul中,其实带有权限认证的功能,那就是ZuulFilter过滤器.ZuulFilter是Zuul中核心组件,通过继承该抽象类,覆写几个关键方法达到自定义调度请求的作用

后台权限校验拦截器

拦截器类 /* * 后台权限校验的拦截器 * *对没有登陆的用户,不可以进行访问 */ public class PrivilegeInterceptor extends MethodFilterInterceptor { @Override //执行拦截的方法 protected String doIntercept(ActionInvocation actionInvocation) throws Exception { //判断session中是否保存了后台用户的信息 AdminUser

深入浅出Git权限校验【转】

在本地计算机与GitHub(或GitLab)进行通信时,传输主要基于两种协议,HTTPS和SSH,对应的仓库地址就是HTTPS URLs和SSH URLs. 首先需要强调的是,HTTPS URLs和SSH URLs对应的是两套完全独立的权限校验方式,主要的区别就是HTTPS URLs采用账号密码进行校验,SSH URLs采用SSH秘钥对进行校验.平时使用的时候我们可以根据实际情况,选择一种即可. HTTPS URLs GitHub官方推荐采用HTTPS URLs的方式,因为该种方式适用面更广(即

Apache shiro之权限校验流程

从张开涛blog学习后整理:http://jinnianshilongnian.iteye.com/blog/2018398 图片原图比较大,建议将图片在新的选项卡打开后100%大小浏览 在权限校验中RolePermissionResolver接口用于将角色所包含的权限全部解析出来(生成Permission实例)

前后端分离与权限校验

我在写web项目时,总是会为权限认证犯愁.在采用前后端分离后,后端只提供接口,项目的路由不再归后端管,而是由代理服务器(Nginx)控制.对于一般公开资源,URL的路由并不依赖于用户的状态,因此光靠代理服务器控制路由就够了.但是一旦涉及私密资源,事情就复杂起来了.对私密资源的访问需要进行权限校验,而这个校验一般由后端提供接口进行.但后端又不负责路由,即此时就做不到直接将不同状态的用户路由到不同资源.遇到这种状况时就需要 先调用后台接口后根据结果改变路由 . 显然,作为路由的发起者,不管是重定向还

类Shiro权限校验框架的设计和实现(2)--对复杂权限表达式的支持

前言: 我看了下shiro好像默认不支持复杂表达式的权限校验, 它需要开发者自己去做些功能扩展的工作. 针对这个问题, 同时也会为了弥补上一篇文章提到的支持复杂表示需求, 特地尝试写一下解决方法. 本文主要借助groovy脚本来实现复杂表达式的计算, 其思想是借鉴了Oval支持复杂表达式(groovy/javascript/ruby)的实现方式. 文章系列: 1. springmvc简单集成shiro  2. 类Shiro权限校验框架的设计和实现  3. 权限系统(RBAC)的数据模型设计 目标

Android 悬浮窗权限校验

原文:Android 悬浮窗权限校验 悬浮窗权限: <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> 权限检验和请求: //检查是否已经授予权限,大于6.0的系统适用,小于6.0系统默认打开,无需理会 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M&&!Settings.canDrawOverlays(

python kafka权限校验client.id

kafka集群有权限校验,在连接时需要加入client.id.但pykafka不能配置该选项.搜索了一下,需要使用confluent-kafka 链接: https://blog.csdn.net/lanyang123456/article/details/80639625 #coding:utf-8 from confluent_kafka import Consumer, KafkaError mybroker = "127.0.0.1:9092" #host client_id

Shiro实现用户对动态资源细粒度的权限校验

前言 在实际系统应用中,普遍存在这样的一种业务场景,需要实现用户对要访问的资源进行动态权限校验. 譬如,在某平台的商家系统中,存在商家.品牌.商品等业务资源.它们之间的关系为:一个商家可以拥有多个品牌,一个品牌下可以拥有多个商品. 一个商家用户可以拥有多个账户,每个账户拥有不同级别的权限. 例如,小王负责商家A下的所有资源的运营工作,小张负责品牌A和品牌A下所有商品的运营工作.而小李负责品牌B Shiro本身提供了RequiresAuthentication.RequiresPermission