温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么在shiro中整合springboot实现前后端分离

发布时间:2021-06-11 16:16:56 来源:亿速云 阅读:569 作者:Leah 栏目:编程语言

这篇文章给大家介绍怎么在shiro中整合springboot实现前后端分离,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

1、shiro整合springboot的配置

package com.hisi.config;   import java.util.LinkedHashMap; import java.util.Map;   import javax.servlet.Filter;   import org.apache.shiro.session.mgt.eis.MemorySessionDAO; import org.apache.shiro.session.mgt.eis.SessionDAO; 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 org.springframework.context.annotation.DependsOn;   import com.hisi.shiro.LoginAuthorizationFilter; import com.hisi.shiro.RestFilter; import com.hisi.shiro.UserRealm;   @Configuration public class ShiroConfig {    /**  * 安全管理器  * @param realm  * @return  */  @Bean  public DefaultWebSecurityManager securityManager(){  DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();  securityManager.setRealm(userRealm());  securityManager.setSessionManager(sessionManager());  return securityManager;  }    /**  * Realm配置  * @return  */  @Bean  public UserRealm userRealm(){  return new UserRealm();  }    /**  * SessionDAO配置  * @return  */  @Bean  public SessionDAO sessionDAO(){  return new MemorySessionDAO();  }    /**  * sessionManager配置  * @param sessionDAO  * @return  */  @Bean  public DefaultWebSessionManager sessionManager(){  DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();  sessionManager.setSessionDAO(sessionDAO());  return sessionManager;  }    /**  * shiroFilter配置  * @param securityManager  * @return  */  @Bean  public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager){    ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();  shiroFilter.setSecurityManager(securityManager());  Map<String, Filter> filters = new LinkedHashMap<String, Filter>();  filters.put("token", new LoginAuthorizationFilter());  filters.put("corsFilter", new RestFilter());  shiroFilter.setFilters(filters);  Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();  filterChainDefinitionMap.put("/user/login", "corsFilter,anon");  filterChainDefinitionMap.put("/user/logout", "corsFilter,anon");  filterChainDefinitionMap.put("/user/**", "corsFilter,token");  shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);  return shiroFilter;  }    /**    * 保证实现了Shiro内部lifecycle函数的bean执行    */   @Bean   public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {     return new LifecycleBeanPostProcessor();   }     /**    * 启用shrio授权注解拦截方式,AOP式方法级权限检查    */   @Bean   @DependsOn(value = "lifecycleBeanPostProcessor") //依赖其他bean的初始化   public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {     return new DefaultAdvisorAutoProxyCreator();   }    /**  * 加入注解的使用,不加入这个注解不生效 使用shiro框架提供的切面类,用于创建代理对象   * @param securityManager  * @return  */   @Bean   public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {     AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();     authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);     return authorizationAttributeSourceAdvisor;   }       }

2、这里配置的两个过滤器RestFilter和LoginAuthorizationFilter,RestFilter是用于解决前后端分离时的跨域问题,服务端在响应头设置可以接受的请求参数

package com.hisi.shiro;   import java.io.IOException; import java.util.Optional;   import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   /**  * 前后端分离RESTful接口过滤器  *   * @author xuguoqin  *  */ public class RestFilter implements Filter {    @Override  public void init(FilterConfig filterConfig) throws ServletException {    }    @Override  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)   throws IOException, ServletException {  HttpServletRequest req = null;  if (request instanceof HttpServletRequest) {   req = (HttpServletRequest) request;  }  HttpServletResponse res = null;  if (response instanceof HttpServletResponse) {   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");   String origin = 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  public void destroy() {    }   }

前者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进行重构

package com.hisi.shiro;   import java.io.IOException; import java.io.PrintWriter; import java.util.Set;   import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;   import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.CollectionUtils; import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; import org.apache.shiro.web.filter.authz.AuthorizationFilter; import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired;   import com.alibaba.fastjson.JSONObject; import com.commons.model.YfpjResult; import com.hisi.mapper.HisiUserMapper; import com.hisi.model.HisiUser; import com.hisi.util.Constant; import com.hisi.util.UserAuthStatusEnum;   /**  * shiro未登录反回状态码  * @author xuguoqin  * @date 2018年5月10日  * @version 1.0  */ public class LoginAuthorizationFilter extends FormAuthenticationFilter {    /**  * 这个方法是未登录需要执行的方法  */  @Override  protected boolean onAccessDenied(ServletRequest request,        ServletResponse response) throws IOException {    HttpServletRequest httpRequest = (HttpServletRequest) request;      HttpServletResponse httpResponse = (HttpServletResponse) response;        Subject subject = getSubject(request, response);      if (subject.getPrincipal() == null) {       //设置响应头  httpResponse.setCharacterEncoding("UTF-8");  httpResponse.setContentType("application/json");  //设置返回的数据  YfpjResult result = YfpjResult.build(UserAuthStatusEnum.UNLOGIN.getCode(), UserAuthStatusEnum.UNLOGIN.getMsg());  //写回给客户端  PrintWriter out = httpResponse.getWriter();  out.write(JSONObject.toJSONString(result));  //刷新和关闭输出流  out.flush();  out.close();     } else {       //设置响应头    httpResponse.setCharacterEncoding("UTF-8");    httpResponse.setContentType("application/json");    //设置返回的数据    YfpjResult result = YfpjResult.build(UserAuthStatusEnum.UNAUTH.getCode(), UserAuthStatusEnum.UNAUTH.getMsg());    //写回给客户端    PrintWriter out = httpResponse.getWriter();    out.write(JSONObject.toJSONString(result));    //刷新和关闭输出流    out.flush();    out.close();     }      return false;   } }

关于怎么在shiro中整合springboot实现前后端分离就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI