• 00034-shiro的配置和使用


    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
     */
    @Component
    public 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;
    
    @Configuration
    public 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>
    
  • 相关阅读:
    VS2005 中关于“LC.EXE已退出,代码为 1”的错误解决方法。
    由于目标机器积极拒绝,无法连接。
    What is Android?
    利用批处理文件和任务计划实现Oracle数据库的自动备份
    就差了一点点....
    由Login.aspx引发编译器错误的解决方法
    都是补丁惹的祸...
    终于结束了
    GIS当然可以很酷
    rar.exe命令行参数与示例
  • 原文地址:https://www.cnblogs.com/jianquan100/p/13683186.html
Copyright © 2020-2023  润新知