shiro整合springboot前后端分离

网友投稿 267 2022-12-19


shiro整合springboot前后端分离

本文实例为大家分享了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;

/**

* shiro权限管理的配置

* @author xuguoqin

* @date 2018年5月4日

* @version 1.0

*/

@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 filters = new LinkedHashMap();

filters.put("token", new LoginAuthorizationFilter());

filters.put("corsFilter", new RestFilter());

shiroFilter.setFilters(filters);

Map filterChainDefinitionMap = new LinkedHashMap();

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);

oxuYegLIFc 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;

imporhttp://t 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;

}

}

4.以后在进行前后端分离的项目开发的时候,可以前端封装一个允许带cookie的ajax请求,同时封装一个统一的未登录或者未授权状态码的判断


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java定义形式及可变参数实例解析
下一篇:简单了解Java多态向上转型相关原理
相关文章

 发表评论

暂时没有评论,来抢沙发吧~