自定义 Filter实现登录权限控制(全面)+登录白名单

一、项目中加入自定义filter实现Filter接口

1、写自定义Filter类

public class SessionFilter implements Filter{
    
    
    public FilterConfig config;
    
    private static Map<String, String> authMap = new HashMap<>();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
	this.config = filterConfig;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
	// 获取request
	HttpServletRequest hrequest = (HttpServletRequest) request;
	// 获取session
	HttpSession session = hrequest.getSession();
	// 能获取response数据,类包装了ServletResponse,可以进行IO操作,返回数据
	HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);
	// 过滤资源后缀参数,已经在web.xml中配置
	String includeStrings = config.getInitParameter("excludeStrings"); 
	// 没有登陆转向页面
	String loginPath = hrequest.getContextPath() + config.getInitParameter("redirectPath");
	// 过滤器是否有效 
	String disabletestfilter = config.getInitParameter("disabletestfilter");
	
	// 过滤器无效,直接跳过
	if (disabletestfilter.toUpperCase().equals("Y")) { 
	    chain.doFilter(request, response);
	    return;
	}
	
	String requestUri = hrequest.getServletPath();
	if ("/".equals(requestUri)) {
	    chain.doFilter(request, response);
	    return;
	}
	
	// 只对指定过滤参数后缀进行过滤,或者请求地址在白名单内
	String[] includeList = includeStrings.split(";");
	if (isContains(requestUri, includeList) || isFilter(requestUri)) {
	    chain.doFilter(request, response);
	    return;
	}
	
	// 判断session中是否有用户登录,如果有过滤
	String user = (String) session.getAttribute("user_session");
	if (user != null) {
	    chain.doFilter(request, response);
	    return;
	}
	// 以上条件都不符合,跳转到登录界面
	wrapper.sendRedirect(loginPath);
	return;
    }

    @Override
    public void destroy() {
	this.config = null;
    }
    
    // 判断请求是否在请求 白名单内
    private static boolean isFilter(String url) {
	if (authMap.isEmpty()) {
	    authMap = cacheProperties("auth");
	    if (authMap.isEmpty()) {
		return true;
	    }
	}
	for (String key : authMap.keySet()) {
	    if (key.contains("**")) {
		key = key.replace("/**", "");
		if (url.startsWith(key)) {
		    return true;
		}
	    } else if (key.equals(url)) {
		return true;
	    }
	}
	return false;
    }
    
    
    public static boolean isContains(String container, String[] regx) {
	for (int i = 0; i < regx.length; i++) {
	    if (container.indexOf(regx[i]) != -1) {
		return true;
	    }
	}
	return false;
    }
    
    // 读取配置文件内容的方法
    public static Map<String, String> cacheProperties(String propName) {
	Map<String, String> map = new HashMap<String, String>();
	ClassPathResource cp = new ClassPathResource(propName + ".properties");
	Properties properties = new Properties();
	try {
	    properties.load(cp.getInputStream());
	} catch (IOException e) {
	    throw new RuntimeException("load "+propName+".properties error!");
	}
	for (Iterator<?> its = properties.keySet().iterator(); its.hasNext();) {
	    String zkey = (String) its.next();
	    map.put(zkey, properties.getProperty(zkey).trim());
	}
	return map;
    }

}

在类中注释的很清楚了,读者如有不懂请留言咨询。

2、白名单配置

#白名单配置,可自行扩展
/common/** = anon
/login = anon
/logon = anno

二、web.xml中配置自定义filter

   <filter>
        <filter-name>SessionFilter</filter-name>
        <filter-class>com.test.filter.SessionFilter</filter-class> <!-- 自定义filter所在包路径 -->
        <init-param>
            <param-name>excludeStrings</param-name>
            <param-value>.css;.js;.jpg;.png</param-value>
        </init-param>
        <init-param>
            <param-name>redirectPath</param-name>
            <param-value>/login</param-value>
        </init-param>
        <init-param>
            <param-name>disabletestfilter</param-name>
            <param-value>N</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>SessionFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

三、测试结果

我们在用户登录时,将用户信息存到session中:

@RequestMapping("logon")
    public String logon(HttpServletRequest request,String userName,String password) {
	if (userName != null) {
	    // 将用户存到session里去
	    HttpSession session = request.getSession();
	    session.setAttribute("user_session", userName);
	    return "index";
	}
	return "login";
    }

1、启动项目跳转到登录页面,当我们不登录直接访问/user/hello这个地址时,我们发现浏览器会自动跳转到登录界面。当我们登录之后,再访问/user/hello时,能跳转到对应的页面。

2、白名单测试,我们把/user/hello加入到我们的白名单中,没有登录访问/user/hello这个地址,我们会发现 直接跳转至相应页面。

至此,自定义过滤器实现完成,过滤器实现的功能如下:

(1)登录权限控制

(2)登录白名单

(3)对一些静态资源文件过滤

欢迎广大读者留言评论。


  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Spring Security中,可以使用Filter实现自定义登录认证拦截器。具体步骤如下: 1. 创建一个实现了javax.servlet.Filter接口的拦截器类,例如:CustomAuthenticationFilter。 ```java public class CustomAuthenticationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 获取请求中的用户名和密码 String username = request.getParameter("username"); String password = request.getParameter("password"); // 自定义认证逻辑 if ("admin".equals(username) && "admin".equals(password)) { // 认证通过 filterChain.doFilter(request, response); } else { // 认证失败 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); } } } ``` 2. 在Security配置类中配置该拦截器。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.addFilterBefore(new CustomAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) .authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } } ``` 在上面的配置中,我们将自定义的拦截器添加到了UsernamePasswordAuthenticationFilter之前,这样就可以在登录认证之前进行自定义认证逻辑的处理。 3. 在登录页面中提交用户名和密码的表单。 ```html <form action="/login" method="post"> <div> <label>用户名:</label> <input type="text" name="username"/> </div> <div> <label>密码:</label> <input type="password" name="password"/> </div> <div> <input type="submit" value="登录"/> </div> </form> ``` 当用户提交表单时,自定义的拦截器会拦截请求并进行自定义认证逻辑的处理,如果认证通过,则继续执行后续的请求处理流程,否则返回认证失败的状态码。 以上就是使用Filter实现登录认证的步骤。需要注意的是,这种方式只适用于简单的认证场景,对于更为复杂的认证需求,建议使用Spring Security提供的AuthenticationProvider进行认证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值