• spring整合shiro


    配置一个存储权限的缓存  ehcache-shiro.xml

    <ehcache updateCheck="false" name="shiroCache">
    
        <defaultCache
                maxElementsInMemory="10000"
                eternal="false"
                timeToIdleSeconds="120"
                timeToLiveSeconds="120"
                overflowToDisk="false"
                diskPersistent="false"
                diskExpiryThreadIntervalSeconds="120"
                />
    </ehcache>

    整合spring配置  applicationContext-shiro.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"  
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       
        xmlns:p="http://www.springframework.org/schema/p"  
        xmlns:context="http://www.springframework.org/schema/context"   
        xmlns:tx="http://www.springframework.org/schema/tx"  
        xmlns:aop="http://www.springframework.org/schema/aop"  
        xsi:schemaLocation="http://www.springframework.org/schema/beans    
        http://www.springframework.org/schema/beans/spring-beans.xsd    
        http://www.springframework.org/schema/aop    
        http://www.springframework.org/schema/aop/spring-aop.xsd    
        http://www.springframework.org/schema/tx    
        http://www.springframework.org/schema/tx/spring-tx.xsd    
        http://www.springframework.org/schema/context    
        http://www.springframework.org/schema/context/spring-context.xsd">
        
        <description>Shiro的配置</description>
        
        <!-- SecurityManager配置 -->
        <!-- 配置Realm域 -->
        <!-- 密码比较器 -->
        <!-- 代理如何生成? 用工厂来生成Shiro的相关过滤器-->
        <!-- 配置缓存:ehcache缓存 -->
        <!-- 安全管理 -->
        <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
            <!-- Single realm app.  If you have multiple realms, use the 'realms' property instead. -->
            <property name="realm" ref="authRealm"/><!-- 引用自定义的realm -->
            <!-- 二级缓存 -->
            <property name="cacheManager" ref="shiroEhcacheManager"/>
        </bean>
    
        <!-- 自定义权限认证 -->
        <bean id="authRealm" class="com.xwer.jk.shiro.AuthorRealm">
            <property name="userService" ref="userService"/>
            <!-- 自定义密码加密算法   密码比较器 -->
            <property name="credentialsMatcher" ref="passwordMatcher"/>
        </bean>
        
        <!-- 设置密码加密策略自定义的密码比较器  md5hash -->
        <bean id="passwordMatcher" class="com.xwer.jk.shiro.CustomerCrednetialsMatcher"/>
    
        <!-- filter-name这个名字的值来自于web.xml中filter的名字 -->
        <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
            <property name="securityManager" ref="securityManager"/>
            <!--登录页面  -->
            <property name="loginUrl" value="/index.jsp"></property>
            <!-- 登录成功后 -->      
            <property name="successUrl" value="/home.action"></property>
            <property name="filterChainDefinitions">
                <!-- /**代表下面的多级目录也过滤 -->
                <value>
                    /index.jsp* = anon
                    /home* = anon
                    /sysadmin/login/login.jsp* = anon
                    /sysadmin/login/logout.jsp* = anon
                    /login* = anon
                    /logout* = anon
                    /components/** = anon
                    /css/** = anon
                    /images/** = anon
                    /js/** = anon
                    /make/** = anon
                    /skin/** = anon
                    /stat/** = anon
                    /ufiles/** = anon
                    /validator/** = anon
                    /resource/** = anon
                    /** = authc
                    /*.* = authc
                </value>
            </property>
        </bean>
    
        <!-- 用户授权/认证信息Cache, 采用EhCache缓存  下面不用多配置 -->
        <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
            <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>
        </bean>
    
        <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
        <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    
        <!-- 生成代理,通过代理进行控制 -->
        <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
              depends-on="lifecycleBeanPostProcessor">
            <property name="proxyTargetClass" value="true"/>
        </bean>
        
        <!-- 安全管理器 -->
        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
            <property name="securityManager" ref="securityManager"/>
        </bean>
        
    </beans>

    自定义比较器类

    /**
     * 自定义密码比较器
     * @author Administrator
     *
     */
    public class CustomerCrednetialsMatcher extends SimpleCredentialsMatcher{
    
        //重写父类方法, token 表示用户在页面输入的用户名和密码,info  表示从数据库取出的数据
        @Override
        public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
            //1.向下转型
            UsernamePasswordToken upToken = (UsernamePasswordToken) token;
            
            //2.将用户 在界面输入的原始加密 进行md5 hash加密   -------  直接使用toString 获取的是char[] 的地址
            //String pwd = Encrypt.md5(upToken.getPassword().toString(), upToken.getUsername());
            String pwd = Encrypt.md5(new String(upToken.getPassword()), upToken.getUsername());
            
            //3.从数据库取出加密的密码
            Object dbPwd = info.getCredentials();
            return this.equals(pwd, dbPwd);
        }
    }


    Encrypt 类

    public class Encrypt {
        /*
         * 散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,
         * 常见的散列算法如MD5、SHA等。一般进行散列时最好提供一个salt(盐),比如加密密码“admin”,
         * 产生的散列值是“21232f297a57a5a743894a0e4a801fc3”,
         * 可以到一些md5解密网站很容易的通过散列值得到密码“admin”,
         * 即如果直接对密码进行散列相对来说破解更容易,此时我们可以加一些只有系统知道的干扰数据,
         * 如用户名和ID(即盐);这样散列的对象是“密码+用户名+ID”,这样生成的散列值相对来说更难破解。
         */
        
        //高强度加密算法,不可逆
        /**
         * 默认加密方式
         * @param password  用户密码
         * @param salt  用户名
         * @return
         */
        public static String md5(String password, String salt){
            return new Md5Hash(password,salt,2).toString();
        }
        
        public static void main(String[] args) {
            System.out.println(new Md5Hash("admin","admin",2).toString());
        }
        
        
    }

    shiro 核心认证授权 AuthorRealm.java

    public class AuthorRealm  extends AuthorizingRealm{
        private final static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
        private UserService userService;
        public void setUserService(UserService userService) {
            this.userService = userService;
        }
        
        //授权
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            //获取当前用户,先根据realm的名字去获取相应的realm
            User user = (User)principals.fromRealm(this.getName()).iterator().next();
            logger.info("用户 {} 授权中.....",user.getUserName());
            //得到权限字符串
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            //获取用户的权限
            Set<Role> roles = user.getRoles();//对象导航,关联级别数据加载,得到当前用户的所有角色    
            List<String> list = new ArrayList<String>();
            for(Role role :roles){
                //对象导航,关联级别数据加载,得到每个角色下的模块列表
                Set<Module> modules = role.getModules();
                for(Module m:modules){
                    if(m.getCtype()==0){
                        //说明是主菜单,组织权限字符串
                        list.add(m.getCpermission());
                    }
                }
            }
    
            info.addStringPermissions(list);
            return info;
        }
        //认证  登录
        protected AuthenticationInfo doGetAuthenticationInfo(
                AuthenticationToken token) throws AuthenticationException {
            UsernamePasswordToken upToken = (UsernamePasswordToken)token;
            
            logger.info("用户 {} 认证中.....",new String(upToken.getUsername()));
            
            //
            String hql = "from User where userName = ?";
            //User user = userService.findUserByName(upToken.getUsername());
            List<User> list = userService.find(hql, User.class, new String[]{upToken.getUsername()});
            
            if(list!=null&& list.size()>0){
            User user = list.get(0);
                //当前用户,用户密码
                AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), getName());
                return info;  //此处如果返回,就会立即 进入密码比较器    
            }
            return  null;
        }
    }
  • 相关阅读:
    php 延迟静态绑定: static关键字
    python分片
    用逗号分隔数字,神奇
    ubuntu 屏幕截图
    js 获取随机数
    netty : NioEventLoopGroup 源码分析
    LinkedList 源码分析
    面向对象
    JS
    网页
  • 原文地址:https://www.cnblogs.com/xwer/p/7512970.html
Copyright © 2020-2023  润新知