shiro整合springboot前后端分离
本文实例为大家分享了shiro整合springboot前后端分离的具体代码,供大家参考,具体内容如下
1、shiro整合springboot的配置
packagecom.hisi.config; importjava.util.LinkedHashMap; importjava.util.Map; importjavax.servlet.Filter; importorg.apache.shiro.session.mgt.eis.MemorySessionDAO; importorg.apache.shiro.session.mgt.eis.SessionDAO; importorg.apache.shiro.spring.LifecycleBeanPostProcessor; importorg.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; importorg.apache.shiro.spring.web.ShiroFilterFactoryBean; importorg.apache.shiro.web.mgt.DefaultWebSecurityManager; importorg.apache.shiro.web.session.mgt.DefaultWebSessionManager; importorg.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; importorg.springframework.context.annotation.DependsOn; importcom.hisi.shiro.LoginAuthorizationFilter; importcom.hisi.shiro.RestFilter; importcom.hisi.shiro.UserRealm; /** *shiro权限管理的配置 *@authorxuguoqin *@date2018年5月4日 *@version1.0 */ @Configuration publicclassShiroConfig{ /** *安全管理器 *@paramrealm *@return */ @Bean publicDefaultWebSecurityManagersecurityManager(){ DefaultWebSecurityManagersecurityManager=newDefaultWebSecurityManager(); securityManager.setRealm(userRealm()); securityManager.setSessionManager(sessionManager()); returnsecurityManager; } /** *Realm配置 *@return */ @Bean publicUserRealmuserRealm(){ returnnewUserRealm(); } /** *SessionDAO配置 *@return */ @Bean publicSessionDAOsessionDAO(){ returnnewMemorySessionDAO(); } /** *sessionManager配置 *@paramsessionDAO *@return */ @Bean publicDefaultWebSessionManagersessionManager(){ DefaultWebSessionManagersessionManager=newDefaultWebSessionManager(); sessionManager.setSessionDAO(sessionDAO()); returnsessionManager; } /** *shiroFilter配置 *@paramsecurityManager *@return */ @Bean publicShiroFilterFactoryBeanshiroFilterFactoryBean(DefaultWebSecurityManagersecurityManager){ ShiroFilterFactoryBeanshiroFilter=newShiroFilterFactoryBean(); shiroFilter.setSecurityManager(securityManager()); Mapfilters=newLinkedHashMap (); filters.put("token",newLoginAuthorizationFilter()); filters.put("corsFilter",newRestFilter()); shiroFilter.setFilters(filters); Map filterChainDefinitionMap=newLinkedHashMap (); filterChainDefinitionMap.put("/user/login","corsFilter,anon"); filterChainDefinitionMap.put("/user/logout","corsFilter,anon"); filterChainDefinitionMap.put("/user/**","corsFilter,token"); shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap); returnshiroFilter; } /** *保证实现了Shiro内部lifecycle函数的bean执行 */ @Bean publicLifecycleBeanPostProcessorlifecycleBeanPostProcessor(){ returnnewLifecycleBeanPostProcessor(); } /** *启用shrio授权注解拦截方式,AOP式方法级权限检查 */ @Bean @DependsOn(value="lifecycleBeanPostProcessor")//依赖其他bean的初始化 publicDefaultAdvisorAutoProxyCreatordefaultAdvisorAutoProxyCreator(){ returnnewDefaultAdvisorAutoProxyCreator(); } /** *加入注解的使用,不加入这个注解不生效使用shiro框架提供的切面类,用于创建代理对象 *@paramsecurityManager *@return */ @Bean publicAuthorizationAttributeSourceAdvisorauthorizationAttributeSourceAdvisor(DefaultWebSecurityManagersecurityManager){ AuthorizationAttributeSourceAdvisorauthorizationAttributeSourceAdvisor=newAuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); returnauthorizationAttributeSourceAdvisor; } }
2、这里配置的两个过滤器RestFilter和LoginAuthorizationFilter,RestFilter是用于解决前后端分离时的跨域问题,服务端在响应头设置可以接受的请求参数
packagecom.hisi.shiro; importjava.io.IOException; importjava.util.Optional; importjavax.servlet.Filter; importjavax.servlet.FilterChain; importjavax.servlet.FilterConfig; importjavax.servlet.ServletException; importjavax.servlet.ServletRequest; importjavax.servlet.ServletResponse; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; /** *前后端分离RESTful接口过滤器 * *@authorxuguoqin * */ publicclassRestFilterimplementsFilter{ @Override publicvoidinit(FilterConfigfilterConfig)throwsServletException{ } @Override publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain) throwsIOException,ServletException{ HttpServletRequestreq=null; if(requestinstanceofHttpServletRequest){ req=(HttpServletRequest)request; } HttpServletResponseres=null; if(responseinstanceofHttpServletResponse){ res=(HttpServletResponse)response; } if(req!=null&&res!=null){ //设置允许传递的参数 res.setHeader("Access-Control-Allow-Headers","Origin,X-Requested-With,Content-Type,Accept,Authorization"); //设置允许带上cookie res.setHeader("Access-Control-Allow-Credentials","true"); Stringorigin=Optional.ofNullable(req.getHeader("Origin")).orElse(req.getHeader("Referer")); //设置允许的请求来源 res.setHeader("Access-Control-Allow-Origin",origin); //设置允许的请求方法 res.setHeader("Access-Control-Allow-Methods","GET,POST,PATCH,PUT,DELETE,OPTIONS"); } chain.doFilter(request,response); } @Override publicvoiddestroy(){ } }
前者ajax请求的时候应该带上参数
$.ajax({ type:"GET", url:url, xhrFields:{ withCredentials:true//携带跨域cookie }, processData:false, success:function(data){ console.log(data); } });
3、LoginAuthorizationFilter主要是对未登录的用户进行过滤然后返回json数据给前端,之前遇到的问题就是shiro配置的loginUrl会导致出现302的问题,在前后端分离的项目中,页面的跳转应该由前端来进行控制,这里前端使用的是vue框架,我需要对shiro中未登录的过滤器FormAuthenticationFilter进行重构
packagecom.hisi.shiro; importjava.io.IOException; importjava.io.PrintWriter; importjava.util.Set; importjavax.servlet.ServletRequest; importjavax.servlet.ServletResponse; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importorg.apache.shiro.SecurityUtils; importorg.apache.shiro.authc.AuthenticationToken; importorg.apache.shiro.subject.Subject; importorg.apache.shiro.util.CollectionUtils; importorg.apache.shiro.web.filter.authc.FormAuthenticationFilter; importorg.apache.shiro.web.filter.authz.AuthorizationFilter; importorg.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.beans.factory.annotation.Autowired; importcom.alibaba.fastjson.JSONObject; importcom.commons.model.YfpjResult; importcom.hisi.mapper.HisiUserMapper; importcom.hisi.model.HisiUser; importcom.hisi.util.Constant; importcom.hisi.util.UserAuthStatusEnum; /** *shiro未登录反回状态码 *@authorxuguoqin *@date2018年5月10日 *@version1.0 */ publicclassLoginAuthorizationFilterextendsFormAuthenticationFilter{ /** *这个方法是未登录需要执行的方法 */ @Override protectedbooleanonAccessDenied(ServletRequestrequest, ServletResponseresponse)throwsIOException{ HttpServletRequesthttpRequest=(HttpServletRequest)request; HttpServletResponsehttpResponse=(HttpServletResponse)response; Subjectsubject=getSubject(request,response); if(subject.getPrincipal()==null){ //设置响应头 httpResponse.setCharacterEncoding("UTF-8"); httpResponse.setContentType("application/json"); //设置返回的数据 YfpjResultresult=YfpjResult.build(UserAuthStatusEnum.UNLOGIN.getCode(),UserAuthStatusEnum.UNLOGIN.getMsg()); //写回给客户端 PrintWriterout=httpResponse.getWriter(); out.write(JSONObject.toJSONString(result)); //刷新和关闭输出流 out.flush(); out.close(); }else{ //设置响应头 httpResponse.setCharacterEncoding("UTF-8"); httpResponse.setContentType("application/json"); //设置返回的数据 YfpjResultresult=YfpjResult.build(UserAuthStatusEnum.UNAUTH.getCode(),UserAuthStatusEnum.UNAUTH.getMsg()); //写回给客户端 PrintWriterout=httpResponse.getWriter(); out.write(JSONObject.toJSONString(result)); //刷新和关闭输出流 out.flush(); out.close(); } returnfalse; } }
4.以后在进行前后端分离的项目开发的时候,可以前端封装一个允许带cookie的ajax请求,同时封装一个统一的未登录或者未授权状态码的判断
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。