jquery ajax 302不跳转,Shiro Ajax 302 跳转问题

版本:

Spring Boot 1.5.4.RELEASE

Shiro 1.4.0

问题

当session超时后,发起Ajax请求(查询更新表格内容),页面没有跳转到登陆画面。

原因

因为使用了Shiro,默认的“authc”是FormAuthenticationFilter 过滤器,该类中的onAccessDenied方法如下,从中可以看出:当访问被拒,并且不是登录请求时,会重定向(302)到登录URL。

protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {

if (isLoginRequest(request, response)) {

if (isLoginSubmission(request, response)) {

if (log.isTraceEnabled()) {

log.trace("Login submission detected. Attempting to execute login.");

}

return executeLogin(request, response);

} else {

if (log.isTraceEnabled()) {

log.trace("Login page view.");

}

//allow them to see the login page ;)

return true;

}

} else {

if (log.isTraceEnabled()) {

log.trace("Attempting to access a path which requires authentication. Forwarding to the " +

"Authentication url [" + getLoginUrl() + "]");

}

// 这里重定向到登录画面

saveRequestAndRedirectToLogin(request, response);

return false;

}

}

如果不是Ajax请求,是没有问题的,浏览器可以正常跳转到登陆画面。如果是jQuery Ajax请示,则ajaxComplete事件最终拿到的response status是redirect之后的status,即访问登陆画面后的响应状态200。

解决方法

重写FormAuthenticationFilter 类的onAccessDenied方法,并判断如果请求是ajax请求,就在header中添加一个需要登录的标识,并且设置response status为401,避免还是200而继续走ajax的成功回调。然后Ajax添加全局事件,当有需要登录的标识时,将页面定位到登录画面。

重写FormAuthenticationFilter

public class MyShiroAuthcFilter extends FormAuthenticationFilter {

public MyShiroAuthcFilter() {

super();

}

@Override

protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {

if (isLoginRequest(request, response)) {

return super.onAccessDenied(request, response);

} else {

if (isAjax((HttpServletRequest) request)) {

HttpServletResponse httpServletResponse = WebUtils.toHttp(response);

httpServletResponse.addHeader("REQUIRE_AUTH", "true");

httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());

} else {

saveRequestAndRedirectToLogin(request, response);

}

return false;

}

}

private boolean isAjax(HttpServletRequest request) {

String requestedWithHeader = request.getHeader("X-Requested-With");

return "XMLHttpRequest".equals(requestedWithHeader);

}

}

配置重写后的filter

@Configuration

public class ShiroConfig {

@Bean

public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {

SpringTemplateEngine engine = new SpringTemplateEngine();

engine.setTemplateResolver(templateResolver);

final ShiroDialect dialect = new ShiroDialect();

engine.addDialect(dialect);

return engine;

}

// @Bean

// public HashedCredentialsMatcher hashedCredentialsMatcher(){

// HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();

// credentialsMatcher.setHashAlgorithmName("SHA1");

// credentialsMatcher.setHashIterations(5);

// credentialsMatcher.setStoredCredentialsHexEncoded(true);

// return credentialsMatcher;

// }

@Bean

public MyShiroRealm myShiroRealm() {

MyShiroRealm myShiroRealm = new MyShiroRealm();

// myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher);

return myShiroRealm;

}

@Bean

public EhCacheManager ehCacheManager() {

EhCacheManager cacheManager = new EhCacheManager();

return cacheManager;

}

@Bean

public SecurityManager securityManager(MyShiroRealm myShiroRealm) {

DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(myShiroRealm);

securityManager.setCacheManager(ehCacheManager());

securityManager.getSessionManager();

return securityManager;

}

// @Bean

// public MyShiroAuthcFilter myShiroAuthcFilter() {

// MyShiroAuthcFilter myShiroAuthcFilter = new MyShiroAuthcFilter();

// return myShiroAuthcFilter;

// }

@Bean

public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {

AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();

authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);

return authorizationAttributeSourceAdvisor;

}

@Bean

public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {

ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();

filter.setSecurityManager(securityManager);

filter.setLoginUrl("/login");

filter.setSuccessUrl("/index");

filter.setUnauthorizedUrl("/403");

filter.setUnauthorizedUrl("/404");

filter.setUnauthorizedUrl("/500");

Map filters = filter.getFilters();

// filters.put("authd", myShiroAuthcFilter());

// 注意这里不要用Bean的方式,否则会报错

filters.put("authd", new MyShiroAuthcFilter());

filters.put("anon", new AnonymousFilter());

filters.put("logout", new LogoutFilter());

filter.setFilters(filters);

Map filterChainDefinitionMap = new LinkedHashMap<>();

filterChainDefinitionMap.put("/resources/**", "anon");

filterChainDefinitionMap.put("/loginSubmit", "anon");

filterChainDefinitionMap.put("/logout", "logout");

filterChainDefinitionMap.put("/**", "authd");

filter.setFilterChainDefinitionMap(filterChainDefinitionMap);

return filter;

}

@Bean

public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {

return new LifecycleBeanPostProcessor();

}

}

Ajax全局事件

$(document).ready(function() {

// 解决session超时,Ajax请求页面不跳转的问题

$(document).ajaxComplete(function(event, xhr, settings) {

if (xhr.getResponseHeader('REQUIRE_AUTH') === 'true') {

window.location.href = ctx + "/index";

}

});

});

参考:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值