预约网站制作后台网站要做权限前端还是后台做
2026/5/21 18:20:47 网站建设 项目流程
预约网站制作,后台网站要做权限前端还是后台做,微信朋友圈产品推广语,我们公司想做个网站SpringBoot集成shiro 数据库设计 sh_user:用户表#xff0c;一个用户可以有多个角色sh_role: 角色表#xff0c;一个角色可以有多个资源sh_resource#xff1a;资源表sh_user_role#xff1a;用户角色中间表sh_role_resource#xff1a;角色资源中间表 首先自定义realm抽象…SpringBoot集成shiro数据库设计sh_user:用户表一个用户可以有多个角色sh_role: 角色表一个角色可以有多个资源sh_resource资源表sh_user_role用户角色中间表sh_role_resource角色资源中间表首先自定义realm抽象类并实现/* by 01130.hk - online tools website : 01130.hk/zh/tiaoseban.html */ package com.itheima.shiro.core; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import javax.annotation.PostConstruct; /** * Description自定义realm的抽象类 */ public abstract class ShiroDbRealm extends AuthorizingRealm { /** * Description 认证方法 * param token token对象 * return 认证信息 */ Override protected abstract AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException ; /** * Description 授权方法 * param principals 令牌对象 * return 授权信息 */ Override protected abstract AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals); /** * Description 自定义密码比较器 * param * return */ PostConstruct public abstract void initCredentialsMatcher(); }实现这个抽象类/* by 01130.hk - online tools website : 01130.hk/zh/tiaoseban.html */ package com.itheima.shiro.core.impl; import com.itheima.shiro.constant.SuperConstant; import com.itheima.shiro.core.ShiroDbRealm; import com.itheima.shiro.core.base.ShiroUser; import com.itheima.shiro.core.base.SimpleToken; import com.itheima.shiro.core.bridge.UserBridgeService; import com.itheima.shiro.pojo.User; import com.itheima.shiro.utils.BeanConv; import com.itheima.shiro.utils.EmptyUtil; import org.apache.shiro.authc.*; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; /** * Description自定义realm的抽象类实现 */ public class ShiroDbRealmImpl extends ShiroDbRealm { Autowired UserBridgeService userBridgeService; /** * Description 认证方法 * param token token对象 * return 认证信息 */ Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //token令牌信息这里的SimpleToken继承了UsernamePasswordToken SimpleToken simpleToken (SimpleToken) token; //根据登录名查询user对象 User user userBridgeService.findUserByLoginName(simpleToken.getUsername()); if (EmptyUtil.isNullOrEmpty(user)){ throw new UnknownAccountException(账号不存在); } //构建认证令牌对象将User对象转换成ShiroUser对象ShiroUser类比Users实体类多了资源列表等属性 ShiroUser shiroUser BeanConv.toBean(user, ShiroUser.class); // 根据用户id获取资源列表并设置到shiroUser对象 shiroUser.setResourceIds(userBridgeService.findResourcesIds(shiroUser.getId())); String slat shiroUser.getSalt(); String password shiroUser.getPassWord(); //构建认证信息对象:1、令牌对象 2、密文密码 3、加密因子 4、当前realm的名称 return new SimpleAuthenticationInfo(shiroUser, password, ByteSource.Util.bytes(slat), getName()); } /** * Description 授权方法 * param principals 令牌对象 * return 授权信息 */ Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 获得令牌对象 ShiroUser shiroUser (ShiroUser) principals.getPrimaryPrincipal(); return userBridgeService.getAuthorizationInfo(shiroUser); } /** * Description 自定义密码比较器 * param * return */ Override public void initCredentialsMatcher() { //指定密码算法 HashedCredentialsMatcher hashedCredentialsMatcher new HashedCredentialsMatcher(SuperConstant.HASH_ALGORITHM); //指定迭代次数 hashedCredentialsMatcher.setHashIterations(SuperConstant.HASH_INTERATIONS); //生效密码比较器 setCredentialsMatcher(hashedCredentialsMatcher); } }SimpleToken类说明package com.itheima.shiro.core.base; import org.apache.shiro.authc.UsernamePasswordToken; /** * Description 自定义tooken */ public class SimpleToken extends UsernamePasswordToken { /** serialVersionUID */ private static final long serialVersionUID -4849823851197352099L; private String tokenType; private String quickPassword; /** * Constructor for SimpleToken * param tokenType */ public SimpleToken(String tokenType, String username,String password) { super(username,password); this.tokenType tokenType; } public SimpleToken(String tokenType, String username,String password,String quickPassword) { super(username,password); this.tokenType tokenType; this.quickPassword quickPassword; } public String getTokenType() { return tokenType; } public void setTokenType(String tokenType) { this.tokenType tokenType; } public String getQuickPassword() { return quickPassword; } public void setQuickPassword(String quickPassword) { this.quickPassword quickPassword; } }userBridgeService接口说明package com.itheima.shiro.core.bridge; import com.itheima.shiro.core.base.ShiroUser; import com.itheima.shiro.pojo.User; import org.apache.shiro.authz.AuthorizationInfo; import java.util.List; /** * Description用户信息桥接后期会做缓存 */ public interface UserBridgeService { /** * Description 查找用户信息 * param loginName 用户名称 * return user对象 */ User findUserByLoginName(String loginName); /** * Description 查询资源ids * param userId 用户id * return 资源id集合 */ ListString findResourcesIds(String userId); /** * Description 鉴权方法 * param shiroUser 令牌对象 * return 鉴权信息 */ AuthorizationInfo getAuthorizationInfo(ShiroUser shiroUser); /** * Description 查询用户对应角色标识list * param userId 用户id * return 角色标识集合 */ ListString findRoleList(String userId); /** * Description 查询用户对应资源标识list * param userId 用户id * return 资源标识集合 */ ListString findResourcesList(String userId); }ShiroUser类说明package com.itheima.shiro.core.base; import com.itheima.shiro.utils.ToString; import lombok.Data; import java.util.List; /** * Description 自定义Authentication对象使得Subject除了携带用户的登录名外还可以携带更多信息 */ Data public class ShiroUser extends ToString { /** serialVersionUID */ private static final long serialVersionUID -5024855628064590607L; /** * 主键 */ private String id; /** * 登录名称 */ private String loginName; /** * 真实姓名 */ private String realName; /** * 昵称 */ private String nickName; /** * 密码 */ private String passWord; /** * 加密因子 */ private String salt; /** * 性别 */ private Integer sex; /** * 邮箱 */ private String zipcode; /** * 地址 */ private String address; /** * 固定电话 */ private String tel; /** * 电话 */ private String mobil; /** * 邮箱 */ private String email; /** * 职务 */ private String duties; /** * 排序 */ private Integer sortNo; /** * 是否有效 */ private String enableFlag; /** * Description 资源列表 */ private ListString resourceIds; public ShiroUser() { super(); } public ShiroUser(String id, String loginName) { super(); this.id id; this.loginName loginName; } Override public int hashCode() { final int prime 31; int result 1; result prime * result ((email null) ? 0 : email.hashCode()); result prime * result ((id null) ? 0 : id.hashCode()); result prime * result ((loginName null) ? 0 : loginName.hashCode()); result prime * result ((mobil null) ? 0 : mobil.hashCode()); return result; } Override public boolean equals(Object obj) { if (this obj) return true; if (obj null) return false; if (getClass() ! obj.getClass()) return false; ShiroUser other (ShiroUser) obj; if (email null) { if (other.email ! null) return false; } else if (!email.equals(other.email)) return false; if (id null) { if (other.id ! null) return false; } else if (!id.equals(other.id)) return false; if (loginName null) { if (other.loginName ! null) return false; } else if (!loginName.equals(other.loginName)) return false; if (mobil null) { if (other.mobil ! null) return false; } else if (!mobil.equals(other.mobil)) return false; return true; } }SuperConstant类说明package com.itheima.shiro.constant; /** * * Description 静态变量 */ public class SuperConstant { /** * 常量是 */ public static final String YES YES; /** * 常量否 */ public static final String NO NO; /** * 匿名用户ID */ public static final String ANON_ID -1; /** * 树形根节点父Id */ public static final String ROOT_PARENT_ID -1; /** * 树形根节点Id */ public static final String ROOT_ID 1; /** * 匿名用户登录名 */ public static final String ANON_LOGIN_NAME ANONYMITY; /** * 匿名用户真实名 */ public static final String ANON_REAL_NAME 匿名; /** * hash算法 */ public static final String HASH_ALGORITHM SHA-1; /** * 计算次数 */ public static final int HASH_INTERATIONS 1024; }ShiroConfig配置package com.itheima.shiro.config; import com.itheima.shiro.core.ShiroDbRealm; import com.itheima.shiro.core.filter.RolesOrAuthorizationFilter; import com.itheima.shiro.core.impl.ShiroDbRealmImpl; import com.itheima.shiro.properties.PropertiesUtil; import lombok.extern.log4j.Log4j2; 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.servlet.SimpleCookie; 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.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import javax.servlet.Filter; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * Description权限管理配置类 */ Configuration // 不配置扫描也可以 ComponentScan(basePackages com.itheima.shiro.core) Log4j2 public class ShiroConfig { //创建cookie对象 Bean(name simpleCookie) public SimpleCookie simpleCookie(){ SimpleCookie simpleCookie new SimpleCookie(); simpleCookie.setName(ShiroSession); return simpleCookie; } //创建权限管理器 Bean(securityManager) public DefaultWebSecurityManager defaultWebSecurityManager(){ DefaultWebSecurityManager securityManager new DefaultWebSecurityManager(); //管理realm securityManager.setRealm(shiroDbRealm()); //管理会话 securityManager.setSessionManager(sessionManager()); return securityManager; } //自定义realm Bean(shiroDbRealm) public ShiroDbRealm shiroDbRealm(){ return new ShiroDbRealmImpl(); } //会话管理器 Bean(sessionManager) public DefaultWebSessionManager sessionManager(){ DefaultWebSessionManager sessionManager new DefaultWebSessionManager(); //关闭会话更新 sessionManager.setSessionValidationSchedulerEnabled(false); //生效cookie sessionManager.setSessionIdCookieEnabled(true); //指定cookie的生成策略 sessionManager.setSessionIdCookie(simpleCookie()); //指定全局会话超时时间 sessionManager.setGlobalSessionTimeout(3600000); return sessionManager; } //创建生命周期的管理 Bean(lifecycleBeanPostProcessor) public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){ return new LifecycleBeanPostProcessor(); } //aop增强使用注解鉴权方式 /** * Description AOP式方法级权限检查 */ Bean DependsOn(lifecycleBeanPostProcessor) public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator new DefaultAdvisorAutoProxyCreator(); defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); return defaultAdvisorAutoProxyCreator; } /** * Description 配合DefaultAdvisorAutoProxyCreator事项开启注解权限校验 */ Bean public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor() { AuthorizationAttributeSourceAdvisor aasa new AuthorizationAttributeSourceAdvisor(); aasa.setSecurityManager(defaultWebSecurityManager()); return aasa; } /** * Description 过滤器链定义 */ private MapString,String filterChainDefinitionMap(){ // 读取authentication.properties配置文件中的过滤器链定义 // PropertiesUtil是读取配置文件的工具类 ListObject list PropertiesUtil.propertiesShiro.getKeyList(); // 必须创建一个有序的map MapString,String map new LinkedHashMap(); for (Object o : list) { String key o.toString(); String val PropertiesUtil.getShiroValue(key); map.put(key, val); } return map; } /** * Description 加载自定义过滤器 */ private MapString, Filter filters(){ MapString,Filter map new HashMap(); // 这里的key表示过滤器的名称 map.put(roles-or, new RolesOrAuthorizationFilter()); return map; } //shiro过滤器管理 Bean(shiroFilter) public ShiroFilterFactoryBean shiroFilterFactoryBean(){ ShiroFilterFactoryBean shiroFilterFactoryBean new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager()); //过滤器指定自己的过滤器 shiroFilterFactoryBean.setFilters(filters()); //过滤器链 shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap()); //登录页面 shiroFilterFactoryBean.setLoginUrl(/login); //未授权页面 shiroFilterFactoryBean.setUnauthorizedUrl(/login); return shiroFilterFactoryBean; } }PropertiesUtil类说明package com.itheima.shiro.properties; import com.itheima.shiro.utils.EmptyUtil; import lombok.extern.log4j.Log4j2; /** * Description 读取Properties的工具类 */ Log4j2 public class PropertiesUtil { public static LinkProperties propertiesShiro new LinkProperties(); /** * 读取properties配置文件信息 */ static { String sysName System.getProperty(sys.name); if (EmptyUtil.isNullOrEmpty(sysName)) { sysName application.properties; } else { sysName .properties; } try { propertiesShiro.load(PropertiesUtil.class.getClassLoader() .getResourceAsStream(authentication.properties)); } catch (Exception e) { log.warn(资源路径中不存在authentication.properties权限文件忽略读取); } } /** * 根据key得到value的值 */ public static String getShiroValue(String key) { return propertiesShiro.getProperty(key); } }authentication.properties配置文件/static/**anon #登录链接不拦截 /login/**anon #访问/resource/**需要有admin的角色 /resource/**roles[dev,SuperAdmin] #其他链接是需要登录的 /**authc 说明过滤器链由路径过滤器组成它是自上而下有序的一个一个去匹配的。如果上面匹配失败则不会匹配下面的内容。自定义过滤器package com.itheima.shiro.core.filter; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.CollectionUtils; import org.apache.shiro.web.filter.authz.AuthorizationFilter; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import java.io.IOException; import java.util.Set; /** * Description角色or判断过滤器,只要当前用户包含传入的角色集合中的一个角色就判断通过 */ public class RolesOrAuthorizationFilter extends AuthorizationFilter { //TODO - complete JavaDoc SuppressWarnings({unchecked}) public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException { Subject subject getSubject(request, response); String[] rolesArray (String[]) mappedValue; if (rolesArray null || rolesArray.length 0) { //no roles specified, so nothing to check - allow access. return true; } SetString roles CollectionUtils.asSet(rolesArray); for (String role : roles) { boolean flag subject.hasRole(role); if (flag){ return flag; } } return false; } }加载自定义过滤器在 ShiroConfig类中配置如下/** * Description 加载自定义过滤器 */ private MapString, Filter filters(){ MapString,Filter map new HashMap(); // 这里的key表示过滤器的名称 map.put(roles-or, new RolesOrAuthorizationFilter()); return map; } //shiro过滤器管理 Bean(shiroFilter) public ShiroFilterFactoryBean shiroFilterFactoryBean(){ ShiroFilterFactoryBean shiroFilterFactoryBean new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager()); //过滤器指定自定义的过滤器 shiroFilterFactoryBean.setFilters(filters()); //过滤器链 shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap()); //登录页面 shiroFilterFactoryBean.setLoginUrl(/login); //未授权页面 shiroFilterFactoryBean.setUnauthorizedUrl(/login); return shiroFilterFactoryBean; }测试自定义过滤器在 authentication.properties配置文件中修改内容如下#访问/resource/**需要有SuperAdmin或者dev的角色 /resource/**roles-or[dev,SuperAdmin]注解方式鉴权本文来自博客园作者NE_STOP转载请注明原文链接https://www.cnblogs.com/alineverstop/p/19475427

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询