• Shiro


    在Spring Context中定义shiroFilter(org.apache.shiro.spring.web.ShiroFilterFactoryBean)时需要为其filterChainDefinitions property赋值,这个属性是个chainName-to-chainDefinition map of chain definitions,用于为URL定义过滤策略。

    比如:

    /404.htm = anon
    /main!main.html = anon
    /**.html = perms[myPerm_1]


    rest:比如/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。

    port:比如/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。

    perms:比如/admins/user/**=perms[user:add:*],perms参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,比如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。

    roles:比如/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,比如/admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。

    anon:比如/admins/**=anon 没有参数,表示可以匿名使用。
    authc:比如/admins/user/**=authc表示需要认证才能使用,没有参数
    authcBasic:比如/admins/user/**=authcBasic没有参数表示httpBasic认证
    ssl:比如/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
    user:比如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查

    一般情况下,我们可以将模块作为一个粒度,例如:

    /blog!**.html = user

    偶尔也会有将每一个URL作为一个授权单位进行控制,例如:

    /blog!doAddNewArticle.html = authc,perms[addArticle]

    但是URL的数量让人头疼,也许可以每开发一个功能的时候打开XML文件写入URL然后同步到SVN,或者我们也可以找一个人专门做这些事情,无论是添加、删除功能还是修改方法名都通知这个人去做...换位思考一下,我不希望我是这个人...

    所以我要把这些URL放在数据库进行管理。我要把他们统统Query出来放到filterChainDefinitions里。
    我需要装配一个Bean,实际上他是一个org.springframework.beans.factory.FactoryBean<Section>的实现。

    <bean id="chainFilterBuff"   class="king.common.ChainFilterBuff">
        <property name="filterChainDefinitions">
        /404.htm = anon
        /main!main.html = anon
        </property>
    </bean>

    然后将其注入:

    <bean id="shiroFilter1" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <property name="loginUrl" value="/main!main.html" />
        <property name="successUrl" value="/main!main.html" />
        <property name="unauthorizedUrl" value="/unAuthorized.htm" />
        <property name="filterChainDefinitionMap" ref="chainFilterBuff" />
    </bean>

    Java代码中implements FactoryBean<Ini.Section>并实现需要Override的method,关键是getObject这个method:

    private String filterChainDefinitions;
    @Override
    public Section getObject() throws Exception {
        Ini ini = new Ini();
        ini.load(filterChainDefinitions);   //先载入XML中定义好的chain
        Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);
        /*
         *  省略读取步骤
         *  继续加入数据库中的chain
         *  section.put("/**", "authc, roles[admin]");
         */
    return section; }

    等等,这些仅仅是定义了权限。
    我们需要在用户访问这些URL的时候去验证一下用户是否具备当前URL权限。
    所以我定义了(事实上我们必须定义一个Realm,ShiroFilterFactoryBean需要SecurityManager,而我们使用的SecurityManager的实现类DefaultWebSecurityManager则需要一个Realm!):

    <bean id="shiroDataBaseRealm" class="king.security.KingMainRealm">

    并且Override了接口定义的method:

    public class KingMainRealm extends AuthorizingRealm {
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo( //授权
                PrincipalCollection principals) {
            UserBean _user = (UserBean) principals.fromRealm(getName()).iterator().next();
            SimpleAuthorizationInfo authInfo = new SimpleAuthorizationInfo();
            /*
             * 省略
             */
            return authInfo;
        }
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo( //认证
                AuthenticationToken token) throws AuthenticationException {
            UserBean user = new UserBean();
            UsernamePasswordToken userToken = (UsernamePasswordToken)token;
            user.setUserName(userToken.getUsername());
            user.setPassword(userToken.getPassword());
                                                                                                                                
            return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
        }
    }

    若已定义了需要请求的URL,用户登录时doGetAuthorizationInfo会被调用,剩下的就是为每一个用户管理这些权限了。
    也许我们可以创建角色关联多个权限,用户关联多个角色,类似这样的设置不同的层次。
    按自己喜欢的方式去做吧 :)

  • 相关阅读:
    tree
    mkdir
    touch
    rename
    dirname
    vue之导入Bootstrap以及jQuery的两种方式
    Vue组件系统
    报错:ERROR! The server quit without updating PID file (/usr/local/var/mysql/chenyuntekiMacBook-Air.local.pid).
    Linux命令
    Vue知识点小总结1
  • 原文地址:https://www.cnblogs.com/kavlez/p/4063885.html
Copyright © 2020-2023  润新知