zoukankan      html  css  js  c++  java
  • shiro(3)shiro核心

    身份认证

    身份认证分三个步骤

    1)提交主题和凭据

    2)进行身份认证

    3)判断是通过,重新提交还是不通过

    验证顺序

    1)调用subject的login方法,提交主体和凭据。

    2)得到对应操作的Security Manager

    3)通过Sceurity Manager得到对应的Autherticator实例

    4)根据配置策略查找对应的桥信息

    5)通过桥信息到对应的配置处理进行身份验证

    验证器

    如果你想配置一个自定义的验证器

    可以在配置文件中使用

    [main]
    ...
    authenticator = com.foo.bar.CustomAuthenticator
    
    securityManager.authenticator = $authenticator
    

    配置策略信息

    AtLeastOneSuccessfulStrategy 如果一个验证成功,则验证结果为成功

    FirstSuccessfulStrategy         只有第一个成功,才算成功

    AllSuccessfulStrategy            所有的都必须成功

    对应的在配置文件中的策略使用如下

    shiro.ini
    
    [main]
    ...
    authcStrategy = org.apache.shiro.authc.pam.FirstSuccessfulStrategy
    
    securityManager.authenticator.authenticationStrategy = $authcStrategy
    
    ...
    
    

    执行顺序

    1)隐式顺序

    blahRealm = com.company.blah.Realm
    ...
    fooRealm = com.company.foo.Realm
    ...
    barRealm = com.company.another.Realm
    

    按上下顺序执行

    2)指定顺序

    blahRealm = com.company.blah.Realm
    ...
    fooRealm = com.company.foo.Realm
    ...
    barRealm = com.company.another.Realm
    
    securityManager.realms = $fooRealm, $barRealm, $blahRealm
    ...
    

    按指定的顺序执行

    授权

    控制谁有权限访问应用程序

    授权的几个要素:权限,角色和用户。

    三种权限的判断方式

    1)编程

    角色判断

    Subject currentUser = SecurityUtils.getSubject();
    
    if (currentUser.hasRole("administrator")) {
        //show the admin button
    } else {
        //don't show the button?  Grey it out?
    }
    

    hasRole(String roleName)                            主题是否已分配给指定的角色

    hasRoles(List<String> roleNames)                是否包含指定的角色

    hasAllRoles(Collection<String> roleNames)   是否包含指定的所有角色

    角色断言

    Subject currentUser = SecurityUtils.getSubject();
    
    //guarantee that the current user is a bank teller and
    //therefore allowed to open the account:
    currentUser.checkRole("bankTeller");
    openBankAccount();
    

    checkRole(String roleName)                       断言是否是指定角色

    checkRoles(Collection<String> roleNames)  断言是否包含以下角色

    checkRoles(String... roleNames)                断言是否包含所有角色

    如果判断指定用户是否有权限访问指定名称的打印机

    那么就会用到下列几个方法

    Permission printPermission = new PrinterPermission("laserjet4400n", "print");
    
    Subject currentUser = SecurityUtils.getSubject();
    
    if (currentUser.isPermitted(printPermission)) {
        //show the Print button
    } else {
        //don't show the button?  Grey it out?
    }
    

    isPermitted(Permission p) 判断主题是否允许执行一个动作

    isPermitted(List<Permission> perms) 是否允许执行一组动作

    isPermittedAll(Collection<Permission> perms) 是否允许执行所有动作

    基于字符串的权限检查

    Subject currentUser = SecurityUtils.getSubject();
    
    if (currentUser.isPermitted("printer:print:laserjet4400n")) {
        //show the Print button
    } else {
        //don't show the button?  Grey it out?
    }
    

    也可以如下使用

    Subject currentUser = SecurityUtils.getSubject();
    
    Permission p = new WildcardPermission("printer:print:laserjet4400n");
    
    if (currentUser.isPermitted(p) {
        //show the Print button
    } else {
        //don't show the button?  Grey it out?
    }
    

    权限断言类似于角色断言。

    2)annocation方式

    The RequiresAuthentication annotation

    @RequiresAuthentication
    public void updateAccount(Account userAccount) {
        //this method will only be invoked by a 
        //Subject that is guaranteed authenticated
        ...
    }
    

    等同于下述代码

    public void updateAccount(Account userAccount) {
        if (!SecurityUtils.getSubject().isAuthenticated()) {
            throw new AuthorizationException(...);
        }
        
        //Subject is guaranteed authenticated here
        ...
    }
    

    The RequiresGuest annotation

    @RequiresGuest
    public void signUp(User newUser) {
        //this method will only be invoked by a 
        //Subject that is unknown/anonymous
        ...
    }
    

    等同于

    public void signUp(User newUser) {
        Subject currentUser = SecurityUtils.getSubject();
        PrincipalCollection principals = currentUser.getPrincipals();
        if (principals != null && !principals.isEmpty()) {
            //known identity - not a guest:
            throw new AuthorizationException(...);
        }
        
        //Subject is guaranteed to be a 'guest' here
        ...
    }
    

    The RequiresPermissions annotation

    @RequiresPermissions("account:create")
    public void createAccount(Account account) {
        //this method will only be invoked by a Subject
        //that is permitted to create an account
        ...
    }
    

    等同于

    public void createAccount(Account account) {
        Subject currentUser = SecurityUtils.getSubject();
        if (!subject.isPermitted("account:create")) {
            throw new AuthorizationException(...);
        }
        
        //Subject is guaranteed to be permitted here
        ...
    }
    

    The RequiresRoles permission

    @RequiresRoles("administrator")
    public void deleteUser(User user) {
        //this method will only be invoked by an administrator
        ...
    }
    

    等同于

    public void deleteUser(User user) {
        Subject currentUser = SecurityUtils.getSubject();
        if (!subject.hasRole("administrator")) {
            throw new AuthorizationException(...);
        }
        
        //Subject is guaranteed to be an 'administrator' here
        ...
    }
    

    The RequiresUser annotation

    @RequiresUser
    public void updateAccount(Account account) {
        //this method will only be invoked by a 'user'
        //i.e. a Subject with a known identity
        ...
    }
    

    等同于

    public void updateAccount(Account account) {
        Subject currentUser = SecurityUtils.getSubject();
        PrincipalCollection principals = currentUser.getPrincipals();
        if (principals == null || principals.isEmpty()) {
            //no identity - they're anonymous, not allowed:
            throw new AuthorizationException(...);
        }
        
        //Subject is guaranteed to have a known identity here
        ...
    }
    

    授权顺序

    1)应用程序调用主题,判断hasRole,isPermitted得到角色或者用户权限的列表。

    2)组成对应的授权方法

    3)协调如何授权

    4)通过桥进行各种方式的授权

    web应用

    配置web.xml

    <listener>
        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
    </listener>
    
    ...
    
    <filter>
        <filter-name>ShiroFilter</filter-name>
        <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>ShiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    如果你愿意你可以自定义一个web应用

    <context-param>
        <param-name>shiroEnvironmentClass</param-name>
        <param-value>com.foo.bar.shiro.MyWebEnvironment</param-value>
    </context-param>
    

    如果你想改变shiro.ini的位置,那么你可以指定

    <context-param>
        <param-name>shiroConfigLocations</param-name>
        <param-value>YOUR_RESOURCE_LOCATION_HERE</param-value>
    </context-param>
    

    shiro.ini中的[urls]配置

    例如:

    ...
    [urls]
    
    /index.html = anon
    /user/create = anon
    /user/** = authc
    /admin/** = authc, roles[administrator]
    /rest/** = authc, rest
    /remoting/rpc/** = authc, perms["remote:invoke"]
    

    假如你有如下设置

    /account/** = ssl, authc
    

    /account下的任何应用程序都将触动ssl和authc链


     


     

    作者:张锋
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
    更多精彩文章可以观注
    微信公众号 soft张三丰

    微信交流群,添加群主微信,邀请入群
  • 相关阅读:
    Spring Cloud Hystrix Dashboard的使用 5.1.3
    Spring Cloud Hystrix 服务容错保护 5.1
    Spring Cloud Ribbon 客户端负载均衡 4.3
    Spring Cloud 如何实现服务间的调用 4.2.3
    hadoop3.1集成yarn ha
    hadoop3.1 hdfs的api使用
    hadoop3.1 ha高可用部署
    hadoop3.1 分布式集群部署
    hadoop3.1伪分布式部署
    KVM(八)使用 libvirt 迁移 QEMU/KVM 虚机和 Nova 虚机
  • 原文地址:https://www.cnblogs.com/skyme/p/2173979.html
Copyright © 2011-2022 走看看