spring security的自定义过滤器实现URL过滤

spring security的自定义过滤器实现URL过滤

最近要实现一个功能,在使用spring security判断完成权限后,还要验证一下URL是否能访问。
因为spring security是用的正则表达式,比如:
http://localhost/order/edit.do?id=13343434
拦截的URL就写成 order/edit.do?*,然后定义成为一个“订单”权限赋予用户。但是并不控制,比如这种到数据的关系,比如
id为132434,1343434,13434的这几个只能让部门经理看,id为1343431的只能让创建人看这种需求,要实现这样的需求,我计划的是在权限拦截之后,实现一个自定义的拦截器,调用业务的manager去实现验证。如果通过,向下执行;如果不通过,那么转向到没有数据权限页面。

比较土的办法,不晓得有没有其他好办法,我没有使用到spring security的AnonymousProcessFilter,我们系统内的用户都是要登录的,所以我决定重写这个filter来实现这个URL过滤的功能。

修改security-context.xml配置文件,增加如下内容:
<beans:bean id="customerAnonymousProcessFilter" class="cn.sccl.um.security.CustomerAnonymousProcessingFilter">
<custom-filter before="ANONYMOUS_FILTER" />
<beans:property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS" />
<beans:property name="key" value="springsecurity"/>
</beans:bean>

其中的ANONYMOUS_FILTER是告诉spring的filter链,我要在哪个位置加入我的自定义fitler

类CustomerAnonymousProcessingFilter.java如下,目前没有实现正则判断URL,而只是通过URL去匹配,这里还需要稍微改进下:
package cn.sccl.um.security;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.security.Authentication;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.anonymous.AnonymousAuthenticationToken;
import org.springframework.security.ui.AuthenticationDetailsSource;
import org.springframework.security.ui.FilterChainOrder;
import org.springframework.security.ui.SpringSecurityFilter;
import org.springframework.security.ui.WebAuthenticationDetailsSource;
import org.springframework.security.userdetails.memory.UserAttribute;
import org.springframework.util.Assert;
import org.springframework.web.context.support.WebApplicationContextUtils;
import cn.sccl.common.ResourceMappingManager;
import cn.sccl.common.ResourceSystemConfiguration;
import cn.sccl.common.util.StringUtil;
public class CustomerAnonymousProcessingFilter extends SpringSecurityFilter
implements InitializingBean {
private AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource();
private String key;
private UserAttribute userAttribute;
private boolean removeAfterRequest = true;
public void afterPropertiesSet() throws Exception {
Assert.notNull(userAttribute);
Assert.hasLength(key);
}
protected boolean applyAnonymousForThisRequest(HttpServletRequest request) {
return true;
}
protected Authentication createAuthentication(HttpServletRequest request) {
AnonymousAuthenticationToken auth = new AnonymousAuthenticationToken(
key, userAttribute.getPassword(), userAttribute
.getAuthorities());
auth.setDetails(authenticationDetailsSource
.buildDetails((HttpServletRequest) request));
return auth;
}

private boolean isJspResources(HttpServletRequest request) {
boolean flag = false;
return flag;
}

protected void doFilterHttp(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (SecurityContextHolder.getContext() != null
&& SecurityContextHolder.getContext().getAuthentication() != null
&& SecurityContextHolder.getContext().getAuthentication()
.isAuthenticated()) {
//获得前面filter登陆的用户loginId
String loginId = SecurityContextHolder.getContext()
.getAuthentication().getName();
//得到请求URL
String url = request.getRequestURI().toLowerCase();
//目前通过properties获得对应的spring bean名称
String managerName = ResourceSystemConfiguration.getResourceMap()
.get(url);
boolean flag = true;
if (StringUtil.isNotBlank(managerName)) {
//要实现资源拦截的manager多implement一个接口ResourceMappingManager
flag = ((ResourceMappingManager) getAppContext(request)
.getBean(managerName)).checkResourceMapping(loginId,
url);
//flag = false; //测试用
if (!flag) {
// 不通过,那么转向没有权限页面
response.sendRedirect(request.getContextPath()
+ "/common/noright.jsp");
return;
}
//放行
}
}
chain.doFilter(request, response);
}

protected ApplicationContext getAppContext(HttpServletRequest request) {
HttpSession session = request.getSession();
ApplicationContext ctx = WebApplicationContextUtils
.getRequiredWebApplicationContext(session.getServletContext());
return ctx;
}
public int getOrder() {
return FilterChainOrder.ANONYMOUS_FILTER;
}
public String getKey() {
return key;
}
public UserAttribute getUserAttribute() {
return userAttribute;
}
public boolean isRemoveAfterRequest() {
return removeAfterRequest;
}
public void setAuthenticationDetailsSource(
AuthenticationDetailsSource authenticationDetailsSource) {
Assert.notNull(authenticationDetailsSource,
"AuthenticationDetailsSource required");
this.authenticationDetailsSource = authenticationDetailsSource;
}
public void setKey(String key) {
this.key = key;
}
public void setRemoveAfterRequest(boolean removeAfterRequest) {
this.removeAfterRequest = removeAfterRequest;
}
public void setUserAttribute(UserAttribute userAttributeDefinition) {
this.userAttribute = userAttributeDefinition;
}
}

用到的类ResourceSystemConfiguration.java如下,这个是参考同事获得properties文件的工具类写的:
package cn.sccl.common;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
public class ResourceSystemConfiguration {
private static CompositeConfiguration config;
private static PropertiesConfiguration propertiesConfig;
static {
config = new CompositeConfiguration();
if (propertiesConfig == null) {
try {
propertiesConfig = new PropertiesConfiguration(
"resouces.properties");
propertiesConfig
.setReloadingStrategy(new FileChangedReloadingStrategy());
config.addConfiguration(propertiesConfig);
} catch (ConfigurationException e) {
e.printStackTrace();
}
}
}
private ResourceSystemConfiguration() {
}
public static String getString(String propertyKey) {
return config.getString(propertyKey);
}
public static String getString(String propertyKey, String defaultValue) {
return config.getString(propertyKey, defaultValue);
}
public static int getInt(String propertyKey) {
return config.getInt(propertyKey);
}
public static int getInt(String key, int defaultValue) {
return config.getInt(key, defaultValue);
}
public static float getFloat(String propertyKey) {
return config.getFloat(propertyKey);
}
public static float getFloat(String propertyKey, float defaultValue) {
return config.getFloat(propertyKey, defaultValue);
}
public static boolean getBoolean(String propertyKey) {
return config.getBoolean(propertyKey);
}
public static boolean getBoolean(String propertyKey, boolean defualtValue) {
return config.getBoolean(propertyKey, defualtValue);
}
public static String[] getStringArray(String propertyKey) {
return config.getStringArray(propertyKey);
}
public static List<String> getStringList(String propertyKey) {
List<String> list = new ArrayList<String>();
String[] strArr = getStringArray(propertyKey);
for (String value : strArr) {
list.add(value);
}
return list;
}
public static Map<String, String> getResourceMap() {
Iterator<?> itkey = config.getKeys();
Map<String, String> map = new HashMap<String, String>();
for (; itkey.hasNext();) {
String key = (String) itkey.next();
String value = config.getString(key);
map.put(key, value);
}
return map;
}
@SuppressWarnings("unchecked")
public static List getList(String propertyKey) {
return config.getList(propertyKey);
}
}

最后一个resources.properties如下,以后可以修改为数据库来存放这个对应关系:
/icpmis/user/edit.do*=userManager,id
我们的UserManagerImpl.java只要实现接口ResourceMappingManager就行了:
public class UserManagerImpl extends BaseManagerImpl<User> implements
UserManager ,ResourceMappingManager
接口ResourceMappingManager.java里面要各个业务manager实现这个接口就行了,到时候MAPPING的这个FITLER就自动调用各个业务方法的MANAGER来验证是否通过:
package cn.sccl.common;
public interface ResourceMappingManager {
public boolean checkResourceMapping(String loginId, String bussinessId);
}
springsecurity过滤指定url【.antMatchers(***).permitAll()】失效分析 springsercurity过滤指定url【antMatchers().permitAll】失效分析 阅读详情

相关推荐

SpringSecurity6解决requestMatchers().permitAll()后依然执行自定义过滤器的问题

Spring容器会自动识别被注册成为Bean对象的Filter过滤器(即继承自Filter对象的类),将这个Bean对象自动注册到SpringBoot的过滤器链中。如果你的过滤器类使用注解注册成为了一个Bean对象,那么他就已经加到了SpringBoot的过滤器链中,所以就算你的SpringSecurity配置中设置了permitAll,可能还会去走SpringBoot的过滤器链。

m0_54250110的博客 1万+

Spring Security介绍(三)过滤器(2)自定义过滤器拦截器

Component@Slf4j@Overridelog.info("进入UrlFilter");@Component@Slf4j@Overridelog.info("进入UrlFilter-one");修改自定义UrlFilter,修改为继承OncePerRequestFilter@Component@Slf4j@Overridelog.info("进入UrlFilter");

w_t_y_y的博客 2848

Spring security/Shiro ---登陆成功后返回登陆前界面<页面重定向>

Spring security ---登陆成功后返回登陆前界面<页面重定向> 问题:在登陆/退出成功后,我们往往通过http.formLogin().successForwardUrl()和http.logout().logoutSuccessUrl()设定操作成功后的回跳页面。我们现在希望在任意界面跳转到登陆界面后,一旦登录成功便会返回登陆前的界面。 解决方法:我们自定义一个过滤器,在Spring security将当前页面(假设为P)重定向到登录页面之前,先将当前页面P的url存入对应的Be

koooooooo5的博客 1557

SpringBoot整合SpringSecurity权限控制(动态拦截url+单点登录)

Slf4j@Component@Resource@Override//获取身份验证详细信息//用于校验mac地址白名单(这里只是打个比方,登录验证中增加的额外字段)//表单输入的用户名//表单输入的密码//校验用户名密码if (!matches) {!");@Override@Component@Resource@Override//任意登录用户名!");//从数据库获取密码//用户拥有的角色// }

在计算机领域混战了5年的java开发工程师,正在向全栈奋斗的路上。目前在学习和分享:Java,springboot,spring,vue,系统开发,服务器运维(可做毕业设计)等相关知识。 3185

Spring Security入门】06-QQ登录实现

准备工作 1、在QQ互联申请成为开发者,并创建应用,得到APP ID 和 APP Key。 2、了解QQ登录时的网站应用接入流程。(必须看完看懂) 为了方便各位测试,直接把我自己申请的贡献出来: 参数 值 APP ID 101386962 APP Key 2a0f820407df400b84a854d054be8b6a 回调地址 http://www...

通往神秘的道路的专栏 1427

spring security3.x学习(22)_关于ip的过滤器

看到电子书的第六章了,我粗略的看了一下,发现第六章的知识很乱,需要前期的基础知识要很好才可以看懂, 所以从这次开始,我自己开始动手写一些例子进行练习(其实基础知识基本上已经学完了,剩下的都是高级配置了) 我先写好了一个模板。以后我们学习就可以根据这个模板进行修改了。(spring mvc + spring security) 下载地址:http://download.csdn

雷哥AI工程化 2024

Spring Security拦截配置

除了基于角色和URL模式的拦截配置,Spring Security还支持自定义过滤器链。这允许我们添加自定义过滤器来处理特定的安全需求。创建一个实现了Filter接口的自定义过滤器类,实现doFilter方法来自定义处理逻辑。配置,将自定义过滤器注册到Spring Security中的过滤器链中。// ...省略其他配置...@Bean// ...省略其他配置...在上述示例代码中,我们创建了一个名为CustomFilter的自定义过滤器,并将其注册到URL模式为。

2301_79108888的博客 2569

Spring Security 自定义登录验证与自定义回调地址

1 配置文件 security-ns.xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org

一个人的博客 1万+

java filter 跳过_java-绕过Spring安全过滤器

我遇到了同样的问题,因此我无法使“ web.ignoring().antMatchers(…)”正常工作.无论如何,我的自定义过滤器一直在被调用.有一种方法可以强制过滤器不影响给定的URL.我找到了这个答案:https://stackoverflow.com/a/19985323/7206367给出了可能允许特定于过滤器的排除的可行解决方案,但是它也可以用于强制执行URL排除覆盖.下面是我对这个问...

weixin_32187037的博客 738

spring-security 3.2.8 配置及部分源码分析

最近本来想研究下spring security oauth2的配置,可是oauth2的配置是基于spring security的,没办法只能先搞懂spring security的配置了 先说下spring security的工作流程 以上是我自己总结的spring security的流程图 如有不正确的地方还请及时指教。 看完流程图之后我们再来分析下spring security的主

ZY_cookie的专栏 1470

spring security动态配置url权限认证

本文介绍的spring security动态配置url权限认证基于的是spring-boot-2.0.0、spring-security 5.X来编写的。 笔者浏览完spring security官方文档之后,发现并没有详细的介绍说明如何动态的配置我们的url权限认证。spring security默认的权限配置确只会在启动工程的时候初始化一次url权限配置。但是实际情况我们项目的权限会随时动态的更改,这样我们就需要重新启动项目以便新配置的权限生效。这样的处理显然不合理。当然spring是具有非常好的拓展

Purpletaro的专栏 3411

spring oauth2】spring oauth2添加自定义拦截验证

前言 搜索关键字:AccessDecisionManager配置 参考文档: https://www.cnblogs.com/chenhonggao/p/9152751.html http://www.mamicode.com/info-detail-2578727.html https://blog.csdn.net/zimou5581/article/details/89511381

Meditation_Crazy 2966

(一)Spring Security Demo 登陆与退出

简单的登陆与退出

young-youth的博客 1618

spring security自定义authenticationProcessingFilter

[url]http://hszdz.iteye.com/blog/337652[/url] [code="xml"] [/code] [code="java"]public Authentication attemptAuthentication( HttpServl...

看的恐惧 1732

SpringSecurity自定义认证

Why SpringSecurity? 在 Web 应用开发中,安全一直是非常重要的一个方面。安全虽然属于应用的非功能性需求,但是应该在应用开发的初期就考虑进来。如果在应用开发的后期才考虑安全的问题,就可能陷入一个两难的境地:一方面,应用存在严重的安全漏洞,无法满足用户的要求,并可能造成用户的隐私数据被攻击者窃取;另一方面,应用的基本架构已经确定,要修复安全漏洞,可能需要对系统的架构做出比较重大的...

★【World Of Moshow 郑锴】★ 1128

Pathway from ACEGI to Spring Security 2.0(2)

The main part of this piece of configuration is the secureResourceFilter, this is a class that implements FilterInvocationDefinitionSource and is called when Spring Security needs to check the Author...

Earl_86 132

Spring Security 动态url权限控制

一、前言 本篇文章将讲述Spring Security 动态分配url权限,未登录权限控制,登录过后根据登录用户角色授予访问url权限 基本环境 spring-boot 2.1.8 mybatis-plus 2.2.0 mysql 数据库 maven项目 Spring Security入门学习可参考之前文章: SpringBoot集成Spring Security入门体验(一)blog....

程序员小明1024 2744

java过滤器往后传参数_Spring security 自定义过滤器实现Json参数传递并兼容表单参数(实例代码)...

依赖org.springframework.bootspring-boot-starter-securityorg.springframework.bootspring-boot-starter-weborg.projectlomboklomboktrueorg.projectlomboklomboktrue配置安全适配类基本配置和配置自定义过滤器package com.study.auth.co...

weixin_33760049的博客 234
上一篇: spring的portlet改进(二)支持CURD标注的groovy充当controller
下一篇: springmvc的bind问题(一)initbinder的调用
magic_dreamer
博客等级 码龄21年 6粉丝 1499原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值