jar:
<shiro.version>1.2.3</shiro.version>
<!-- shiro --><dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>${shiro.version}</version></dependency><dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>${shiro.version}</version></dependency><dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>${shiro.version}</version></dependency><dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>${shiro.version}</version></dependency>
自定义自定义Realm:
import com.xmdishi.fmp.model.po.business.BusinessMenuPo;import com.xmdishi.fmp.model.po.business.BusinessUserPo;import com.xmdishi.fmp.model.qo.business.BusinessUserQo;import com.xmdishi.fmp.service.business.BusinessMenuService;import com.xmdishi.fmp.service.business.BusinessUserService;import org.apache.shiro.authc.*;import org.apache.shiro.authc.credential.CredentialsMatcher;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;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 org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.stereotype.Component;import java.util.HashSet;import java.util.List;import java.util.Set;/** * 自定义Realm * @author cjianquan * @date 2020/4/6 * @param * @return */@Componentpublic class CustomRealm extends AuthorizingRealm { @Autowired private BusinessUserService businessUserService; @Autowired private BusinessMenuService businessMenuService; private static Logger logger=LoggerFactory.getLogger(CustomRealm.class); public CustomRealm() { logger.info("CustomRealm===================="); } @Override public String getName() { return "CustomRealm"; } @Bean(name = "credentialsMatcher") public HashedCredentialsMatcher credentialsMatcher(){ HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(); credentialsMatcher.setHashAlgorithmName("md5"); credentialsMatcher.setHashIterations(1); return credentialsMatcher; } @Override public void setCredentialsMatcher(@Qualifier("credentialsMatcher")CredentialsMatcher credentialsMatcher){ super.setCredentialsMatcher(credentialsMatcher); } /** * realm受权办法 从输出参数principalCollection失去身份信息 依据身份信息到数据库查找权限信息 将权限信息增加给受权信息对象 * 返回 受权信息对象(判断用户拜访url是否在权限信息中没有体现) */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { BusinessUserPo user = (BusinessUserPo) principalCollection.getPrimaryPrincipal(); String roleIds = user.getRoleIds(); List<String> btnList = null; try{ btnList = businessMenuService.queryBtnsByRoles(roleIds); }catch (Exception e){ e.printStackTrace(); } // 用户权限列表 Set<String> permsSet = new HashSet<String>(); if(btnList!=null && btnList.size()>0){ permsSet.addAll(btnList); } SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.setStringPermissions(permsSet); return info; } /** * 表单认证过滤器认证时会调用自定义Realm的认证办法进行认证,胜利回到index.do,再跳转到index.jsp页面 * * 前提:表单认证过滤器收集和组织用户名和明码信息封装为token对象传递给此办法 * * token:封装了身份信息和凭证信息 2步骤:比对身份 信息;比对凭证 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = (String) token.getPrincipal(); String password = new String((char[]) token.getCredentials()); // 查问用户信息 BusinessUserQo userQo = new BusinessUserQo(); userQo.setUserName(username); List<BusinessUserPo> userList = null; BusinessUserPo businessUserPo = null; try{ userList = this.businessUserService.query(userQo); if(userList!=null && userList.size()>0){ businessUserPo = userList.get(0); } }catch (Exception e){ e.printStackTrace(); } // 账号不存在 if (businessUserPo == null ) { throw new UnknownAccountException("账号不存在!"); } // 明码谬误 if (!password.equals(businessUserPo.getPassword())) { throw new IncorrectCredentialsException("账号或明码不正确!"); } // 账号未调配角色 if (businessUserPo.getRoleIds() == null ) { throw new UnknownAccountException("账号未调配角色!"); } //cjianquan 2020/2/8 登录胜利,查问菜单 try{ List<BusinessMenuPo> menuList = this.businessMenuService.queryByRoles(businessUserPo.getRoleIds()); businessUserPo.setMenuList(menuList); }catch (Exception e){ e.printStackTrace(); } SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(businessUserPo, password, getName()); return info; }}
web.xml 增加 :
<filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> <!-- targetBeanName??spring?shiro??????bean?id??? --> <init-param> <param-name>targetBeanName</param-name> <param-value>shiroFilter</param-value> </init-param></filter><filter-mapping> <filter-name>shiroFilter</filter-name> <!-- ????url???shiro?????? --> <url-pattern>/*</url-pattern></filter-mapping>
SpringShiroConfig:
import com.xmdishi.fmp.business.shiro.CustomRealm;import org.apache.shiro.cache.ehcache.EhCacheManager;import org.apache.shiro.mgt.SecurityManager;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.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.beans.factory.config.MethodInvokingFactoryBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.DependsOn;import java.util.LinkedHashMap;import java.util.Map;@Configurationpublic class SpringShiroConfig { @Autowired private CustomRealm realm; public SpringShiroConfig() { System.out.println("SpringShiroConfig init ......"); } @Bean(name = "lifecycleBeanPostProcessor") public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } @Bean @DependsOn("lifecycleBeanPostProcessor") public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator(); creator.setProxyTargetClass(true); creator.setUsePrefix(true); return creator; } @Bean public MethodInvokingFactoryBean getMethodInvokingFactoryBean(@Qualifier("securityManager")SecurityManager securityManager) { MethodInvokingFactoryBean methodInvokingFactoryBean=new MethodInvokingFactoryBean(); methodInvokingFactoryBean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager"); methodInvokingFactoryBean.setArguments(new Object[]{securityManager}); return methodInvokingFactoryBean; } //get @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager")SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } //get @Bean(name = "shiroFilter") public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager")SecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setLoginUrl("/index.jsp"); shiroFilterFactoryBean.setSuccessUrl("/index.jsp"); shiroFilterFactoryBean.setUnauthorizedUrl("/index.jsp"); shiroFilterFactoryBean.setSecurityManager(securityManager); loadShiroFilterChain(shiroFilterFactoryBean); return shiroFilterFactoryBean; } //get @Bean(name = "sessionManager") public DefaultWebSessionManager sessionManager(){ DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); sessionManager.setGlobalSessionTimeout(86400000); sessionManager.setDeleteInvalidSessions(true); return sessionManager; } //get @Bean(name = "shiroCacheManager") public EhCacheManager shiroCacheManager(){ EhCacheManager shiroCacheManager = new EhCacheManager(); shiroCacheManager.setCacheManagerConfigFile("classpath:shiro-ehcache.xml"); return shiroCacheManager; } //get @Bean(name = "securityManager") public DefaultWebSecurityManager securityManager(@Qualifier("shiroCacheManager") EhCacheManager shiroCacheManager, @Qualifier("sessionManager") DefaultWebSessionManager sessionManager) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(realm); securityManager.setCacheManager(shiroCacheManager); securityManager.setSessionManager(sessionManager); return securityManager; } //get private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean) { Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); filterChainDefinitionMap.put("/index.jsp", "anon"); filterChainDefinitionMap.put("/common/**", "anon"); filterChainDefinitionMap.put("/**/login/**", "anon"); filterChainDefinitionMap.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); }}
登录办法:
@RequestMapping(value = "login") @ResponseBody public Object login(@ModelAttribute("user")LoginUser user, HttpServletRequest request) { BaseResp resp = new BaseResp(); String access_token = ""+ IdUtils.id(); JSONObject jsonObject = new JSONObject(); /** * 应用Shiro编写认证操作 */ try { //1.获取Subject Subject subject = SecurityUtils.getSubject(); //2.封装用户数据 UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), CommonUtils.md5(user.getPassword()));// UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(),user.getPassword()); //3.执行登录办法 subject.login(token); jsonObject.put("access_token",access_token); jsonObject.put("user",rtnUser((BusinessUserPo)subject.getPrincipal())); resp.setData(jsonObject); } catch (UnknownAccountException e) { resp.setSuccess(false); resp.setMsg(e.getMessage()); e.printStackTrace(); } catch (IncorrectCredentialsException e) { resp.setSuccess(false); resp.setMsg(e.getMessage()); e.printStackTrace(); }catch (Exception e){ resp.setSuccess(false); resp.setMsg("零碎异样,请稍后再试"); e.printStackTrace(); } return resp; }
前台页面应用:
jsp:
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>
按钮权限:
<div class="layui-btn-container"> <shiro:hasPermission name="taskProgress:add"> <button class="layui-btn layui-btn-sm" data-type="addRec">增加</button> </shiro:hasPermission> <shiro:hasPermission name="taskProgress:del"> <button class="layui-btn layui-btn-sm layui-btn-danger" data-type="delRec">删除</button> </shiro:hasPermission></div>