spring boot shrio前后端分离,未登陆时shrio返回json数据,而不是重定向,自定义ajax,封装ajax

spring boot shrio前后端分离,未登陆时shrio返回json数据,而不是重定向

springboot shrio整合后,默认在未登录的情况下shrio会将请求重定向到登陆页面,但是我配置了nginx的https后,发起的请求是https,但是如果是未登录,shrio则会将请求重定向到登陆页面,这个时候出现问题,这个重定向的请求是http,前端js就会报错。

解决思路,配置shrio自定义拦截器,如果是未登录的 返回对ajax友好的json数据。

并且我们希望前端能根据返回的数据进行判断用户是否登录,所以这里要对ajax进行封装。

关键步骤:添加shrio自定义拦截器 

package com.ning.config;

import java.io.IOException;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.shiro.web.filter.authc.UserFilter;

import com.alibaba.fastjson.JSON;
import com.ning.utils.R;
public class MyFilter extends UserFilter{

	@Override
	protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
		response.setContentType("application/json; charset=utf-8");
		response.getWriter().print(JSON.toJSON(R.error(403, "请登录")));
	}
	
}

将拦截器添加到shrio配置类中 

 

package com.ning.config;

import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.ning.utils.UserRealm;

/**
 * Shiro配置
 *
 */
@Configuration
public class ShiroConfig {

    @Bean(name = "sessionManager")
    public SessionManager sessionManager(){
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        //设置session过期时间为1小时(单位:毫秒),默认为30分钟
        sessionManager.setGlobalSessionTimeout(60 * 60 * 1000 * 24 * 7);
        sessionManager.setSessionValidationSchedulerEnabled(true);
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        return sessionManager;
    }

    @Bean(name = "securityManager")
    public SecurityManager securityManager(UserRealm userRealm, SessionManager sessionManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //Realm 主要是从realm中获取相应的身份信息
        securityManager.setRealm(userRealm);
        securityManager.setSessionManager(sessionManager);

        return securityManager;
    }

    //传统方式是使用web.xml配置的。在shiro中使用@Bean注解方式实现过滤器。
    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        Map filters = shiroFilter.getFilters();
        filters.put("authc", new MyFilter());
        shiroFilter.setFilters(filters);
        //shiroFilter.setLoginUrl("/login.html");//默认访问的首页面
        //shiroFilter.setSuccessUrl("/index.html");
        //shiroFilter.setUnauthorizedUrl("/");
        
        //anon代表是匿名访问方式,比如index.html是匿名访问的即不区分用户、谁都可以访问。
        Map filterMap = new LinkedHashMap<>();
        filterMap.put("/public/**", "anon");
        filterMap.put("/favicon.ico", "anon");
        filterMap.put("/public/plugins/**", "anon");
        filterMap.put("/public/plugins/UE/jsp/**", "anon");
        filterMap.put("/webjars/**", "anon");
        filterMap.put("/api/**", "anon");
        filterMap.put("/originInfo/**", "anon");
        filterMap.put("/app/app/checkVersion", "anon");//app检查版本
        filterMap.put("/app/app/getNewVersion", "anon");//app下载最新版本
        	
        //swagger配置
        filterMap.put("/swagger**", "anon");
        filterMap.put("/v2/api-docs", "anon");
        filterMap.put("/swagger-resources/configuration/ui", "anon");

        filterMap.put("/login.html", "anon");
        filterMap.put("/index.html", "anon");
        filterMap.put("/json", "anon");
        filterMap.put("/sys/login", "anon");
        filterMap.put("/captcha.jpg", "anon");//认证码
        filterMap.put("/upload/ckUploadImg", "anon");
        filterMap.put("/upload/**", "anon");
        filterMap.put("/upload/ck/**", "anon");
        
        //authc代表是必须认证访问的。/**代表是除上面配置以外的其它资源。
        filterMap.put("/**", "authc");
        shiroFilter.setFilterChainDefinitionMap(filterMap);
        return shiroFilter;
    }

    @Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
        proxyCreator.setProxyTargetClass(true);
        return proxyCreator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

}

请注意关键部分代码 

Map filters = shiroFilter.getFilters();
        filters.put("authc", new MyFilter());

这里filters.put("authc", new MyFilter());map添加的key值必须为authc,之前我自定义是无效的。

 这样如果用户在未登录状态发起请求,就会返回我们自定义的json字符串。下面是自定义ajax:

function Ajax(type,url,param,callback,isjson){
  		var contentType = "application/x-www-form-urlencoded;charset=UTF-8";
  		if(isjson){
  			contentType = "application/json;charset=UTF-8";
 		}
  		$.ajax({
	  		type: type,
		    url: url,
		    data: param,
		    contentType:contentType,
		    success: function(r){
		    	if(r.code == 403){
		    		alert("请重新登陆")
		    	}else{
		    		callback(r);
		    	}
			}
	  	})
  	}
  	Ajax("post","/json",{"json":6667},function(data){
  		console.log(data)
  	})

 对ajax的成功回调函数进行封装,也可以对请求参数进行封装。方便使用。

你可能感兴趣的:(spring,boot,shrio,ajax)