禁止ajax访问shiro管理的登录页面
在使用shiro的时候,对于用户权限的管理,相信很多人都已经很熟悉了。
今天,我这里简单的记录一下我自己调试过程中遇到的问题。主要是登录的操作,禁止通过ajax的方式进行访问。
shiro中,登录过程拒绝ajax的访问操作,主要在FormAuthenticationFilter里面实现的。更具体的说,应该是自己重写AccessControlFilter方法中的onAccessDenied方法。
为什么要禁止ajax的登录?安全的考虑!
先看看自己应用中重写的RdFormAuthenticationFilter,它继承于FormAuthenticationFilter,至于FormAuthenticationFilter和AccessControlFilter的关系,自己看shiro的源码吧。
public class RdFormAuthenticationFilter extends FormAuthenticationFilter {
private String passwordParam;
@Autowired
@Qualifier("mqmKefuService")
private IMqmKefuService mksService;
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue)
throws Exception {
if (request.getAttribute(getFailureKeyAttribute()) != null) {
return true;
}
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
if (isLoginSubmission(request, response)) {
return executeLogin(request, response);
} else {
if ("XMLHttpRequest".equalsIgnoreCase(httpServletRequest.getHeader("X-Requested-With"))
|| request.getParameter("ajax") != null) {
HttpServletResponse res = WebUtils.toHttp(response);
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
return true;
}
}
@Override
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
HttpServletResponse httpServletResponse = (HttpServletResponse)response;
String username = (String)SecurityUtils.getSubject().getPrincipal();
if(username == null){
return true;
}
MqmKefu user = mksService.selectByUsername(username);
SecurityUtils.getSubject().getSession().setAttribute(Constants.CURRENT_USER, user);
if ("XMLHttpRequest".equalsIgnoreCase(httpServletRequest.getHeader("X-Requested-With"))
|| request.getParameter("ajax") != null) {
// 是ajax请求
httpServletRequest.getRequestDispatcher("/login/timeout/success").forward(httpServletRequest, httpServletResponse);
} else {
//httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + this.getSuccessUrl());
String redirectUrl = httpServletRequest.getContextPath() + "/home";
SavedRequest sr = WebUtils.getSavedRequest(request);
//当用户地址的请求不是在地址栏输入,而是在页面上直接点击登录,那么SavedRequest返回值将会是空的。
if(sr != null) {
redirectUrl = sr.getRequestUrl();
}
httpServletResponse.sendRedirect(redirectUrl);
}
return false;
}
public String getPasswordParam() {
return passwordParam;
}
public void setPasswordParam(String passwordParam) {
this.passwordParam = passwordParam;
}
}
AAAA。这里,重点是下面的这个代码片段:
if ("XMLHttpRequest".equalsIgnoreCase(httpServletRequest.getHeader("X-Requested-With"))
|| request.getParameter("ajax") != null) {
HttpServletResponse res = WebUtils.toHttp(response);
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
如何测试呢?很简单!
1. 将shiro的配置中,重写LogoutFilter,并将其redirectUrl的值配置为自己想要的内容,而不是原来默认的DEFAULT_REDIRECT_URL(值为/)。例如,将redirectUrl改为登录的url,这里是/usr/login.
2. 将前端页面的退出,一种用ajax的post或者get方式触发,一种用href直接配置url。
2.1 针对退出url (/usr/logout)以ajax的方式触发事件到后台,代码逻辑将会进入上述代码AAAA,且此时HTTP请求头部含有X-Requested-With。前端将收到401的错误,页面不跳转。
2.2 针对退出url以a标签的href方式,直接由浏览器以http调用后台服务的方式,则不会进入AAAA的代码逻辑。
针对上述的LogoutFilter的重写,可以看看配置文件:
<bean id="sysUserFilter" class="com.roomdis.mqr.infra.shiro.SysUserFilter"/>
<bean id="sysLogoutFilter" class="com.roomdis.mqr.infra.shiro.RdLogoutFilter">
<property name="redirectUrl" value="/user/login"/>
</bean> <bean id="jCaptchaValidateFilter" class="com.roomdis.mqr.infra.shiro.JCaptchaValidateFilter">
<property name="jcaptchaEbabled" value="true"/>
<property name="jcaptchaParam" value="jcaptchaCode"/>
<property name="failureKeyAttribute" value="shiroLoginFailure"/>
</bean> <bean id="filterChainManager" class="com.roomdis.mqr.infra.shiro.RdDefaultFilterChainManager">
<property name="loginUrl" value="/user/login" />
<property name="successUrl" value="/home" />
<property name="unauthorizedUrl" value="/unauth" />
<property name="customFilters">
<util:map>
<entry key="authc" value-ref="authcFilter"/>
<entry key="sysUser" value-ref="sysUserFilter"/>
<entry key="jCaptchaValidate" value-ref="jCaptchaValidateFilter"/>
<entry key="logout" value-ref="sysLogoutFilter" />
</util:map>
</property>
<property name="defaultFilterChainDefinitions">
<value>
/ = anon
/*.png = anon
/css/* = anon
/js/** = anon
/image/* = anon
/index.html = anon
/user/login = jCaptchaValidate,authc
/jcaptcha* = anon
/jcaptcha.jsp = anon
/home = sysUser,user
/logout = logout
<!-- /home = authc, perms[/home] perms 表示需要该权限才能访问的页面 -->
</value>
</property>
</bean>
上述配置的红色部分,是重写LogoutFilter的对应bean的信息。
蓝色部分,要特别注意,logout的url,权限部分处理,必须是和自己代码逻辑中的重定向部分一致使用。例如这里的/logout,对应代码逻辑中的地方(红色)如下:
/**
* logout 即常说的登出操作
*
* @param req
* @param rsp
* @param model
* @return
*/
@GET
@Path("/user/logout")
@Produces(MediaType.APPLICATION_JSON)
public void logout(@Context HttpServletRequest req, @Context HttpServletResponse rsp){
Map<String, Object> infoMap = new HashMap<String, Object>();
String basePath = basePath(req);
String usernamep = req.getParameter("username");
infoMap.put("basePath", basePath);
SecurityUtils.getSubject().getSession().removeAttribute(Constants.CURRENT_USER);
try {
rsp.sendRedirect(req.getContextPath() + "/logout");
} catch (IOException e) {
e.printStackTrace();
}
}
前端的代码:
<p class="checkmove">
<span class="fl sp_title">
<#if username??>
<label id="username">${username}</label>
<a class=logout-btn href="${basePath}/user/logout">退出</a> #能够正常运行,即不会触发401的错误的用法
<!--
<button class=button id="leave">退出</button> #这样子用,配合后台的ajax的方式触发,就会出现401的错误
-->
</#if>
<select>
<option value="">上线</option>
<option value="">离开</option>
<option value="">隐身</option>
<option value="">下线</option>
</select>
</span>
</p>
下面上一个图,看看我的项目雏形!

禁止ajax访问shiro管理的登录页面的更多相关文章
- session过期,拦截ajax请求并跳转登录页面
1.方法一 :1.1使用filter 和ajaxsetup 对ajax进行拦截并跳转登录页面 public void doFilter(ServletRequest request, ServletR ...
- 禁止盗链,强制回登录页面web.config配置
<system.web> <compilation debug="true" targetFramework="4.5" /> < ...
- windwsform登录页面
简单登录设计: 读取用户名密码 数据库表 实体类 数据访问类: 隐藏登录页面: 回车快捷键: 传值到main窗口:
- Shiro 整合SpringMVC 并且实现权限管理,登录和注销
Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大 ...
- Shiro 整合SpringMVC 并实现权限管理,登录和注销
Shiro 整合SpringMVC 并且实现权限管理,登录和注销 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring S ...
- ajax Session失效如何跳转到登录页面
在Struts应用中,我们发出的请求都会经过 相应的拦截器进行相关处理,一般都会有一个用户登录拦截(Session失效拦截):一般请求的话,如果Session失效时,我们会跳到登录页面,可是如果我们采 ...
- 11月10日上午ajax基础知识、用ajax做登录页面、用ajax验证用户名是否可用、ajax动态调用数据库
1.ajax的基础知识 ajax是结合了jquery.php等几种技术延伸出来的综合运用的技术,不是新的内容.ajax也是写在<script>标签里面的. 如果使用ajax一定是要有1个处 ...
- 重写ajax方法实现异步请求session过期时跳转登录页面
jQuery(function($){ // 备份jquery的ajax方法 var _ajax=$.ajax; // 重写ajax方法, $.ajax=function(opt){ var _suc ...
- WebForm.aspx 页面通过 AJAX 访问WebForm.aspx.cs类中的方法,获取数据
WebForm.aspx 页面通过 AJAX 访问WebForm.aspx.cs类中的方法,获取数据 WebForm1.aspx 页面 (原生AJAX请求,写法一) <%@ Page Langu ...
随机推荐
- python day04 作业答案
1. 1) li=['alex','WuSir','ritian','barry','wenzhou'] print(len(li)) 2) li=['alex','WuSir','ritian',' ...
- Python MRO_C3
class A: pass class B(A): pass class C(A): pass class D(B, C): pass class E(C, A): pass class F(D, E ...
- [转]谈谈 Bias-Variance Tradeoff
https://liam0205.me/2017/03/25/bias-variance-tradeoff/ 谢谢原作者! 谈谈 Bias-Variance Tradeoff 发表于 2017 年 0 ...
- INS-20802 Oracle Cluster Verification Utility failed解释说明
背景:安装RAC,安装GI集群管理软件时,在最后快结束时,总是报如上INS-错误 #官方文档:error 说明;字符串解析失败 INS-20802: string failed. Cause: The ...
- [LeetCode&Python] Problem 905: Sort Array By Parity
Given an array A of non-negative integers, return an array consisting of all the even elements of A, ...
- ortp 发送RTP实例
参考源代码目录src/tests/rtpsend.c ortp_init(); ortp_scheduler_init(); ortp_set_log_level_mask(O ...
- java-类与类,类与接口,接口与接口的关系
1.类与类: - 继承关系,只能单继承,可以多层继承. 2.类与接口: - 实现关系,可以单实现,也可以多实现. - 并且还可以在继承一个类的同时实现多个接口. - * 例:class Demo ex ...
- (21)jq动画
jq动画的优点 优点: 1.可以知道动画结束的表示(结束的回调函数) 2.可以利用jq动画插件完成复杂的动画 动画有三个参数:动画的样式是字典.动画持续的事件,动画结束回调函数 <!DOCTYP ...
- djkstra nlogn
#include<bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> usi ...
- python基础(八)——多线程
[root@bogon python]# cat test.py #!/usr/bin/ptyhon import thread import time def print_time(threadNa ...