zoukankan      html  css  js  c++  java
  • Shiro —— 从一个简单的例子开始

    一、Shiro是用来做权限的。

    二、权限

    1.基本概念:

    (1)安全实体:要保护的数据。

    (2)权限:是否有能力去操作(查看、修改、删除 )保护的数据。

    2、权限的两个特性

    (1)权限的继承性:A 包含 B,B无权限,但A有权限,此时B 的权限即为 A 的权限。如大厦里有公共厕所,进出大厦需要门禁,所以公共厕所的权限就是大厦的门禁权限。

    (2)最近路劲匹配:如大厦某层有卫生间,要想到此卫生间需要有该层电梯权限,此时该卫生间的权限为该层电梯的权限,而不是大厦的门禁权限。

    3.几个关键词

    (1)认证:验证用户身份,即验证登录的用户名密码是否正确,用户是否被锁死。

    (2)授权:决定是否有权限访问受保护的资源。

    (3)加密:保护或隐藏受保护的资源。

    (4)会话管理

    (5)单点登录(SSO)

    三、Shiro

    1.核心组件

    (1)Subject:当前用户。

    (2)Shiro SecurityManager:Shiro 大管家。

    (3)Realm:用于访问数据库。

    2.Shiro SecurityManager

    Shiro 的大管家管理着 Shiro 下的认证、授权、会话管理、缓存管理、以及 Realm 访问数据库,贯穿于始终的是加密。

    3.用户、角色、权限

    (1)概念:

    • 用户:通俗来讲,指的就是要登录的用户名密码。
    • 角色:权限的集合。
    • 权限:是否有能力去做某件事。

    (2)关系

    • 权限作用于角色,角色是权限的一个集合
    • 角色作用于用户,用户是什么角色。

    (3)维系关系

    • 用户——角色:用户角色中间表。
    • 角色——权限:角色权限中间表。

    (4)以上所有的这些都归 Shiro 大管家来管理。

    四、一个简单的官方的例子

    1.需要导入的 jar 包。

    2.官方demo。

    /*
     * Licensed to the Apache Software Foundation (ASF) under one
     * or more contributor license agreements.  See the NOTICE file
     * distributed with this work for additional information
     * regarding copyright ownership.  The ASF licenses this file
     * to you under the Apache License, Version 2.0 (the
     * "License"); you may not use this file except in compliance
     * with the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing,
     * software distributed under the License is distributed on an
     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     * KIND, either express or implied.  See the License for the
     * specific language governing permissions and limitations
     * under the License.
     */
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.config.IniSecurityManagerFactory;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.session.Session;
    import org.apache.shiro.subject.Subject;
    import org.apache.shiro.util.Factory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    
    /**
     * Simple Quickstart application showing how to use Shiro's API.
     *
     * @since 0.9 RC2
     */
    public class Quickstart {
    
        private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
    
    
        public static void main(String[] args) {
    
            // The easiest way to create a Shiro SecurityManager with configured
            // realms, users, roles and permissions is to use the simple INI config.
            // We'll do that by using a factory that can ingest a .ini file and
            // return a SecurityManager instance:
    
            // Use the shiro.ini file at the root of the classpath
            // (file: and url: prefixes load from files and urls respectively):
            Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
            SecurityManager securityManager = factory.getInstance();
    
            // for this simple example quickstart, make the SecurityManager
            // accessible as a JVM singleton.  Most applications wouldn't do this
            // and instead rely on their container configuration or web.xml for
            // webapps.  That is outside the scope of this simple quickstart, so
            // we'll just do the bare minimum so you can continue to get a feel
            // for things.
            SecurityUtils.setSecurityManager(securityManager);
    
            // Now that a simple Shiro environment is set up, let's see what you can do:
    
            // get the currently executing user:
            Subject currentUser = SecurityUtils.getSubject();
    
            // Do some stuff with a Session (no need for a web or EJB container!!!)
            Session session = currentUser.getSession();
            session.setAttribute("someKey", "aValue");
            String value = (String) session.getAttribute("someKey");
            if (value.equals("aValue")) {
                log.info("-->Retrieved the correct value! [" + value + "]");
            }
    
            // let's login the current user so we can check against roles and permissions:
            if (!currentUser.isAuthenticated()) {
                UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
                token.setRememberMe(true);
                try {
                    currentUser.login(token);
                } catch (UnknownAccountException uae) {
                    log.info("-->There is no user with username of " + token.getPrincipal());
                } catch (IncorrectCredentialsException ice) {
                    log.info("-->Password for account " + token.getPrincipal() + " was incorrect!");
                } catch (LockedAccountException lae) {
                    log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                            "Please contact your administrator to unlock it.");
                }
                // ... catch more exceptions here (maybe custom ones specific to your application?
                catch (AuthenticationException ae) {
                    //unexpected condition?  error?
                }
            }
    
            //say who they are:
            //print their identifying principal (in this case, a username):
            log.info("-->User [" + currentUser.getPrincipal() + "] logged in successfully.");
    
            //test a role:
            if (currentUser.hasRole("schwartz")) {
                log.info("-->May the Schwartz be with you!");
            } else {
                log.info("Hello, mere mortal.");
            }
    
            //test a typed permission (not instance-level)
            if (currentUser.isPermitted("lightsaber:weild")) {
                log.info("-->You may use a lightsaber ring.  Use it wisely.");
            } else {
                log.info("Sorry, lightsaber rings are for schwartz masters only.");
            }
    
            //a (very powerful) Instance Level permission:
            if (currentUser.isPermitted("winnebago:drive:eagle5")) {
                log.info("-->You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  " +
                        "Here are the keys - have fun!");
            } else {
                log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
            }
    
            //all done - log out!
            currentUser.logout();
    
            System.exit(0);
        }
    }

    说明:获取 SecurityManager ,认证,认证失败的几种情况,成功登陆后是否拥有某个角色,某个角色是否有某个权限。

    [users]
    root = secret, admin
    guest = guest, guest
    presidentskroob = 12345, president
    darkhelmet = ludicrousspeed, darklord, schwartz
    lonestarr = vespa, goodguy, schwartz
    
    [roles]
    admin = *
    schwartz = lightsaber:*
    goodguy = winnebago:drive:eagle5

    说明:Shiro.ini 文件,用来维系用户——角色——权限之间的关系。

    3.ini 文件说明

    [users]:用户名=密码,角色1,角色2

    [roles]:角色=权限1,权限2

    权限:

    (1)用简单的字符串来表示一个权限。如:user

    (2)多层次管理:如:user:query,user:edit,user:query,edit。第一部分为操作的领域,第二部分为执行的操作。可以使用通配符:user:*,*:query

    (3)实例级权限:域:操作:实例

    如:user:edit:manager 只能对 user 中的 manager 进行 edit。

    通配符:user:edit:*、user:*:*、user:*:manager

    等价:user:edit==user:edit:*、user == user:*:* 只能从字符串结尾处省略。

    (4)可对比官方例子学习。

    五、总结:

    介绍了权限的基础,介绍了 Shiro 的 HelloWorld,要明白其中重要的部分,如:认证、授权,以及Shiro 是如何来做这两件事情的。介绍官方demo 的 ini 配置方式,只是想更加深刻的去理解

    Shiro 的管理器,认证,授权,角色,权限等等这些概念。

  • 相关阅读:
    随机森林算法参数调优
    BAYES和朴素BAYES
    阿里云 金融接口 token PHP
    PHP mysql 按时间分组 表格table 跨度 rowspan
    MySql按周,按月,按日分组统计数据
    PHP 获取今日、昨日、本周、上周、本月的等等常用的起始时间戳和结束时间戳的时间处理类
    thinkphp5 tp5 会话控制 session 登录 退出 检查检验登录 判断是否应该跳转到上次url
    微信 模板消息
    php 腾讯 地图 api 计算 坐标 两点 距离 微信 网页 WebService API
    php添加http头禁止浏览器缓存
  • 原文地址:https://www.cnblogs.com/solverpeng/p/5884043.html
Copyright © 2011-2022 走看看