微前端架构如何改变企业的开发模式与效率提升
660
2023-01-25
SpringBoot配置shiro安全框架的实现
首先引入pom
ShiroConfig.java
package com.jx.cert.web.framework.config.shiro;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.Filter;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import com.jx.cert.web.framework.config.shiro.filter.KickoutSessionControlFilter;
import com.jx.cert.web.framework.config.shiro.filter.ShiroPermissionsFilter;
import com.jx.cert.web.framework.config.shiro.filter.SystemLogoutFilter;
import com.jx.common.utils.CacheConstants;
/**
* @ClassName: gyu
* @Description: TODO(shrio配置)
* @author gangyu
* @date 2018年12月4日 下午2:28:07
*/
@Configuration
public class ShiroConfig {
Logger log=LoggerFactory.getLogger(ShiroConfig.class);
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.prot}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.database}")
private int database;
//注意这里需要设置成 static 否则 @Value 注入不了数据
@Bean(name = "lifecycleBeanPostProcessor")
public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
log.debug("-----------------Shiro-工厂类注入开始");
Map
//权限过滤器
filterMap.put("perms", new ShiroPermissionsFilter());
shiroFilterFactoryBean.setFilters(filterMap);
// 配置shiro安全管理器 SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 指定要求登录时的链接
shiroFilterFactoryBean.setLoginUrl("/login");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index");
// filterChainDefinitions-=map必须用:LinkedHashMap,因为它必须保证有序
Map
//对外应用开发接口不验证
filterChainDefinitionMap.put("/app/**", "anon");
filterChainDefinitionMap.put("/ajaxLogin", "anon");
// 放开验证码
filterChainDefinitionMap.put("/public/getGifCode", "anon");
// 退出
filterChainDefinitionMap.put("/logout", "logout");
//TODO 全部放行
// filterChainDefinitionMap.put("/manage/**", "anon[*]");
//公共资源
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon");
// authc:所有url都必须认证通过才可以访问;
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
log.debug("-----------------Shiro-工厂类注入成功");
return shiroFilterFactoryBean;
}
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("MD5");//散列算法:这里使用MD5算法;
hashedCredentialsMatcher.setHashIterations(1);//散列的次数,比如散列两次,相当于 md5(md5(""));
return hashedCredentialsMatcher;
}
//权限缓存到内存
@Bean(name = "shiroRealm")
@DependsOn("lifecycleBeanPostProcessor")
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
myShiroRealm.setCacheManager(new MemoryConstrainedCacheManager());
myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return myShiroRealm;
}
@Bean(name = "securityManager")
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
// 自定义session管理 使用redis
securityManager.setSessionManager(sessionManager());
// 自定义缓存实现 使用redis
securityManager.setCacheManager(cacheManager());
return securityManager;
}
/**
* 配置shiro redisManager
* @return
*/
public RedisManager redisManager() {
RedisManager redisManager = new RedisManager();
redisManager.setHost(host);
redisManager.setPort(port);
redisManager.setTimeout(timeout);
// redisManager.setPassword(password);
redisManager.setDatabase(database);
return redisManager;
}
//自定义sessionManager
@Bean
public SessionManager sessionManager() {
MySessionManager mySessionManager = new MySessionManager();
mySessionManager.setSessionDAO(redisSessionDAO());
//默认1个小时session过期
mySessionManager.setGlobalSessionTimeout(CacheConstants.SHIRO_SESSION_MS);
return mySessionManager;
}
/**
* RedisSessionDAO shiro sessionDao层的实现 通过redis
*/
@Bean
public RedisSessionDAO redisSessionDAO() {
RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
redisSessionDAO.setRedisManager(redisManager());
return redisSessionDAO;
}
/**
* cacheManager 缓存 redis实现
* @return
*/
@Bean
public RedisCacheManager cacheManager() {
RedisCacheManager redisCacheManager = new RedisCacheManager();
redisCacheManager.setRedisManager(redisManager());
redisCacheManager.setExpire(CacheConstants.USER_DATA_TTL);
return redisCacheManager;
}
}
MyShiroRealm.java
package com.jx.cert.web.framework.config.shiro;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.jx.cert.web.framework.config.shiro.exception.SysUsreNotLoginAPPException;
import com.jx.cert.web.framework.config.shiro.exception.SystemNotExistException;
import com.jx.common.utils.SysCode;
import com.jx.core.api.model.vo.cert.SysPermission;
import com.jx.core.api.model.vo.cert.SysRole;
import com.jx.core.api.model.vo.cert.SysSystem;
import com.jx.core.api.model.vo.cert.SysUser;
import com.jx.core.api.service.business.cert.SysPermissionService;
import com.jx.core.api.service.business.cert.SysRoleService;
import com.jx.core.api.service.business.cert.SysSystemService;
import com.jx.core.api.service.business.cert.SysUserService;
public class MyShiroRealm extends AuthorizingRealm {
private Logger logger = LoggerFactory.getLogger(MyShiroRealm.class);
@Autowired
private SysUserService sysUserService;
@Autowired
private SysRoleService sysRoleService;
@Autowired
private SysPermissionService sysPermissionService;
@Autowired
private SysSystemService systemService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
logger.info("####################开始配置权限####################");
SysUser user = (SysUser) principals.getPrimaryPrincipal();
if (user != null) {
//权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
List
List
for (SysRole role : user.getRoleList()) {
roleStrlist.add(role.getRoleName());
}
for (SysPermission permission : user.getPermissList()) {
perminsStrlist.add(permission.getUrl());
}
//用户的角色集合
authorizationInfo.addRoles(roleStrlist);
//用户的菜单按钮权限集合
authorizationInfo.addStringPermissions(perminsStrlist);
return authorizationInfo;
}
return null;
}
/*主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
logger.info("####################身份认证####################");
String userStr = (String) token.getPrincipal();
SysUser user = sysUserService.getUserByUserName(userName);
//认证系统用户
List
user.setRoleList(roleList);//获取用户角色
List
SysPermission permis=new SysPermission();
list.add(permis);
user.setPermissList(list);//获取用户权限
return new SimpleAuthenticationInfo(user, DigestUtils.md5Hex(user.getPassword()),getName());
}
}
ShiroTagsFreeMarkerCfg.java
package com.jx.cert.web.framework.config.shiro;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import com.jagregory.shiro.freemarker.ShiroTags;
import freemarker.template.TemplateModelException;
/**
* @ClassName: ShiroTagsFreeMarkerCfg
* @Description: TODO(ftl shiro 标签)
* @author gangyu
* @date 2018年12月5日 下午5:16:27
*
*/
@Component
public class ShiroTagsFreeMarkerCfg {
@Autowired
private FreeMarkerConfigurer freeMarkerConfigurer;
@PostConstruct
public void setSharedVariable() throws TemplateModelException {
freeMarkerConfigurer.getConfiguration().setSharedVariable("shiro", new ShiroTags());
}
}
ShiroPermissionsFilter.java
/**
* @Title: ShiroPermissionsFilter.java
* @Package com.jx.cert.web.config.shiro
* @Description: TODO(用一句话描述该文件做什么)
* @author gangyu
* @date 2018年12月5日 上午11:47:00
* @version V1.0
*/
package com.jx.cert.web.framework.config.shiro.filter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.jx.cert.web.framework.config.shiro.ShiroUtil;
import com.jx.common.utils.Result;
import com.jx.common.utils.enums.CodeEnum;
import com.jx.core.api.model.vo.cert.SysPermission;
import com.jx.core.api.model.vo.cert.SysUser;
/**
* @ClassName: ShiroPermissionsFilter
* @Description: TODO(权限验证)
* @author gangyu
* @date 2018年12月5日 上午11:47:00
*/
public class ShiroPermissionsFilter extends PermissionsAuthorizationFilter {
private static final Logger logger = LoggerFactory.getLogger(ShiroPermissionsFilter.class);
/**
* 权限检测验证
*/
@Override
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
logger.info("----------权限校验-------------");
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String reqUrl=request.getRequestURI();
List
String contextPath=request.getContextPath();
reqUrl=reqUrl.substring(contextPath.length()+1, reqUrl.length());
String header = request.getHeader("X-Requested-With");
boolean isAjax = "XMLHttpRequest".equals(header);
SysUser user=ShiroUtil.getUser();
if(!new Gson().toJson(permsList).contains(reqUrl)){
if (isAjax) {
logger.info("----------AJAX请求拒绝-------------");
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
response.getWriter().write(new Gson().toJson(new Result(CodeEnum.NOT_PERMISSION)));
} else {
logger.info("----------普通请求拒绝-------------");
response.sendRedirect(request.getContextPath()+"/403");
}
return false;
}else {
return true;
}
}
}
ShiroUtil.java
package com.jx.cert.web.framework.config.shiro;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import com.jx.core.api.model.vo.cert.SysUser;
public class ShiroUtil {
/**
* 获取当前 Subject
*
* @return
*/
public static Subject getSubject() {
return SecurityUtils.getSubject();
}
/**
* 获取shiro指定的sessionKey
*
* @param key
* @param
* @return
*/
public static
Session session = getSession();
return session != null ? (T) session.getAttribute(key) : null;
}
/**
* 设置shiro指定的sessionKey
*
* @param key
* @param value
*/
public static void setSessionAttr(String key, Object value) {
Session session = getSession();
session.setAttribute(key, value);
}
/**
* 获取当前用户对象
*
* @return
*/
public static SysUser getUser() {
if(getSubject().isAuthenticated()){
return (SysUser) getSubject().getPrincipals().getPrimaryPrincipal();
}
return null;
}
/**
* 获取当前用户对象UserID
*
* @return
*/
public static String getUserId() {
return getUser().getUserId();
}
/**
* 移除shiro指定的sessionKey
*
* @param key
*/
public static void removeSessionAttr(String key) {
Session session = getSession();
if (session != null)
session.removeAttribute(key);
}
/**
* 验证当前用户是否属于该角色
*
* @param roleName 角色名称
* @return 属于该角色:true,否则false
*/
public static boolean hasRole(String roleName) {
return getSubject() != null && roleName != null
&& roleName.length() > 0 && getSubject().hasRole(roleName);
}
/**
* shiro 中获取session
*
* @return session
*/
public static Session getSession() {
return getSubject().getSession();
}
/**
* 验证当前用户是否属于以下所有角色
* 多权限“,”分割
*
* @param roleNames 权限名称
* @return 属于:true,否则false
*/
public static boolean hasAllRoles(String roleNames) {
boolean hasAllRole = true;
Subject subject = getSubject();
if (subject != null && roleNames != null && roleNames.length() > 0) {
for (String role : roleNames.split(",")) {
if (!subject.hasRole(role.trim())) {
hasAllRole = false;
break;
}
}
}
return hasAllRole;
}
/**
* 验证当前用户是否属于以下任意一个角色
* 多权限“,”分割
* @param rohttp://leNames
* @return
*/
public static boolean hasAnyRoles(String roleNames) {
boolean hasAnyRole = false;
Subject subject = getSubject();
if (subject != null && roleNames != null && roleNames.length() > 0) {
for (String role : roleNames.split(",")) {
if (subject.hasRole(role.trim())) {
hasAnyRole = true;
break;
}
}
}
return hasAnyRole;
}
}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~