溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

shiro中怎么利用springboot實(shí)現(xiàn)前后端分離

發(fā)布時(shí)間:2021-07-08 17:16:26 來(lái)源:億速云 閱讀:240 作者:Leah 欄目:編程語(yǔ)言

shiro中怎么利用springboot實(shí)現(xiàn)前后端分離,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

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; /** * shiro權(quán)限管理的配置 * @author xuguoqin * @date 2018年5月4日 * @version 1.0 */@Configurationpublic 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; }  /**   * 保證實(shí)現(xiàn)了Shiro內(nèi)部lifecycle函數(shù)的bean執(zhí)行   */  @Bean  public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {    return new LifecycleBeanPostProcessor();  }   /**   * 啟用shrio授權(quán)注解攔截方式,AOP式方法級(jí)權(quán)限檢查   */  @Bean  @DependsOn(value = "lifecycleBeanPostProcessor") //依賴其他bean的初始化  public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {    return new DefaultAdvisorAutoProxyCreator();  }  /** * 加入注解的使用,不加入這個(gè)注解不生效 使用shiro框架提供的切面類,用于創(chuàng)建代理對(duì)象  * @param securityManager * @return */  @Bean  public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {    AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();    authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);    return authorizationAttributeSourceAdvisor;  }    }

2、這里配置的兩個(gè)過(guò)濾器RestFilter和LoginAuthorizationFilter,RestFilter是用于解決前后端分離時(shí)的跨域問(wèn)題,服務(wù)端在響應(yīng)頭設(shè)置可以接受的請(qǐng)求參數(shù)

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接口過(guò)濾器 *  * @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) {  //設(shè)置允許傳遞的參數(shù)  res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");  //設(shè)置允許帶上cookie  res.setHeader("Access-Control-Allow-Credentials", "true");  String origin = Optional.ofNullable(req.getHeader("Origin")).orElse(req.getHeader("Referer"));  //設(shè)置允許的請(qǐng)求來(lái)源  res.setHeader("Access-Control-Allow-Origin", origin);  //設(shè)置允許的請(qǐng)求方法  res.setHeader("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS"); } chain.doFilter(request, response); }  @Override public void destroy() {  } }

前者ajax請(qǐng)求的時(shí)候應(yīng)該帶上參數(shù)

$.ajax({type: "GET",url: url,xhrFields: {  withCredentials: true // 攜帶跨域cookie},processData: false,success: function(data) {  console.log(data); }});

3、LoginAuthorizationFilter主要是對(duì)未登錄的用戶進(jìn)行過(guò)濾然后返回json數(shù)據(jù)給前端,之前遇到的問(wèn)題就是shiro配置的loginUrl會(huì)導(dǎo)致出現(xiàn)302的問(wèn)題,在前后端分離的項(xiàng)目中,頁(yè)面的跳轉(zhuǎn)應(yīng)該由前端來(lái)進(jìn)行控制,這里前端使用的是vue框架,我需要對(duì)shiro中未登錄的過(guò)濾器FormAuthenticationFilter進(jìn)行重構(gòu)

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未登錄反回狀態(tài)碼 * @author xuguoqin * @date 2018年5月10日 * @version 1.0 */public class LoginAuthorizationFilter extends FormAuthenticationFilter {  /** * 這個(gè)方法是未登錄需要執(zhí)行的方法 */ @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) {      //設(shè)置響應(yīng)頭 httpResponse.setCharacterEncoding("UTF-8"); httpResponse.setContentType("application/json"); //設(shè)置返回的數(shù)據(jù) YfpjResult result = YfpjResult.build(UserAuthStatusEnum.UNLOGIN.getCode(), UserAuthStatusEnum.UNLOGIN.getMsg()); //寫回給客戶端 PrintWriter out = httpResponse.getWriter(); out.write(JSONObject.toJSONString(result)); //刷新和關(guān)閉輸出流 out.flush(); out.close();    } else {      //設(shè)置響應(yīng)頭   httpResponse.setCharacterEncoding("UTF-8");   httpResponse.setContentType("application/json");   //設(shè)置返回的數(shù)據(jù)   YfpjResult result = YfpjResult.build(UserAuthStatusEnum.UNAUTH.getCode(), UserAuthStatusEnum.UNAUTH.getMsg());   //寫回給客戶端   PrintWriter out = httpResponse.getWriter();   out.write(JSONObject.toJSONString(result));   //刷新和關(guān)閉輸出流   out.flush();   out.close();    }     return false;  }}

4.以后在進(jìn)行前后端分離的項(xiàng)目開發(fā)的時(shí)候,可以前端封裝一個(gè)允許帶cookie的ajax請(qǐng)求,同時(shí)封裝一個(gè)統(tǒng)一的未登錄或者未授權(quán)狀態(tài)碼的判斷

關(guān)于shiro中怎么利用springboot實(shí)現(xiàn)前后端分離問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI