7.shiro官网入门案例ini

之前的缓存redis整合有问题,虽然也可以用但是不能跨域不能sso单点登陆,所以决定一步步来先学最基础的shiro再去整合springboot吧.下面开始入门!

Quickstart.java

1.获取正在执行的用户:

Subject currentUser = SecurityUtils.getSubject();

2.设置属于用户的session:

Session session = currentUser.getSession();
session.setAttribute( "someKey", "aValue" );

该会话是一个特定于shio的实例,它提供了常规httpsession所提供的大部分内容,但也提供了一些额外的好处,还有一个很大的区别:它不需要HTTP环境!
如果在web应用程序中部署,默认情况下会话将基于HttpSession。但是,在非web环境中,比如这个简单的快速入门,Shiro默认情况下会自动使用它的企业会话管理。这意味着您可以在任何层的应用程序中使用相同的API,而不管部署环境如何。
3.上面的Subject实例表示当前用户,但是谁是当前用户呢?嗯,他们是匿名的——也就是说,直到他们至少登录一次。让我们这样做:(证明你是谁)

if ( !currentUser.isAuthenticated() ) {
	//没有登陆 会把用户数据封装
    UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
  //记住我功能
    token.setRememberMe(true);
    //登陆
    currentUser.login(token);
}

就是这样!再简单不过了。
但是如果他们的登录尝试失败了呢?你可以捕获各种特定的异常,告诉你到底发生了什么,并允许你处理和相应的反应:

try {
    currentUser.login( token );
    //login()中传入了用户数据 它会去Realm中验证数据
} catch ( UnknownAccountException uae ) {
   //找不到账户
} catch ( IncorrectCredentialsException ice ) {
    //密码不匹配
} catch ( LockedAccountException lae ) {
    //尝试次数过多
}
    ... more types exceptions to check if you want ...
} catch ( AuthenticationException ae ) {
   //未知其他错误
}

4.现在,我们有了一个登录用户。我们还能做什么?
我们来看看他们是谁:

//print their identifying principal (in this case, a username): 
log.info( "User [" + currentUser.getPrincipal() + "] logged in successfully." );

我们也可以测试他们是否有特定的角色:

if ( currentUser.hasRole( "schwartz" ) ) {
    log.info("May the Schwartz be with you!" );
} else {
    log.info( "Hello, mere mortal." );
}

我们还可以看到他们是否有权限对某种类型的实体采取行动:

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.");
}
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!");
}

小菜一碟,对吧?
最后,当用户使用应用程序完成时,他们可以注销:

currentUser.logout(); //removes all identifying information and invalidates their session too.
	这就是在应用程序开发人员级别使用Apache Shiro的核心。虽然有一些相当复杂的东西在幕后进行,使这个工作如此优雅,这就是它的全部。

但是您可能会问自己,“但是谁负责在登录期间获取用户数据(用户名和密码、角色和权限等),以及谁在运行时实际执行这些安全检查?”通过实现Shiro所称的领域并将该领域插入到Shiro的配置中,您可以做到这一点。
然而,如何配置域在很大程度上取决于您自己
(自己配置Realm决定认证规则等)

后面官网给了一个入门项目,按照该项目我自己搞的:
1.准备一个maven项目
pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>shiro-first-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <java.version>1.8</java.version>
    </properties>


    <dependencies>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.4.1</version>
        </dependency>
        <!-- 需要一个日志框架来对接门面日志框架.Shiro uses SLF4J for logging.  We'll use the 'simple' binding-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.21</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.21</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>1.7.2</version>
        </dependency>
        <!--门面日志-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging-api</artifactId>
            <version>1.1</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.shiro.ini配置在resource下

# -----------------------------------------------------------------------------
# Users and their (optional) assigned roles
# username = password, role1, role2, ..., roleN
#账号 root 密码 secret 角色admin    账号 guest 密码 guest 角色 guest
# -----------------------------------------------------------------------------
[users]
root = secret, admin
guest = guest, guest
presidentskroob = 12345, president
darkhelmet = ludicrousspeed, darklord, schwartz
lonestarr = vespa, goodguy, schwartz

# -----------------------------------------------------------------------------
# Roles with assigned permissions
# roleName = perm1, perm2, ..., permN      角色名的权限设置
# -----------------------------------------------------------------------------
[roles]
admin = *
schwartz = lightsaber:*
goodguy = winnebago:drive:eagle5

3.你的测试类

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.session.UnknownSessionException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;

public class ShiroTest {

    public static void main(String[] args) {
        System.out.println ("我的第一个 Apache Shiro Application");
        //加载.ini配置文件,并获取工厂(相当于数据库的数据)
        Factory<SecurityManager> factory = new IniSecurityManagerFactory ("classpath:shiro.ini");
        //获取安全管理者实例(将数据加载给安全管理者)
        SecurityManager securityManager = factory.getInstance ( );
        //将安全管理者放入全局对象
        SecurityUtils.setSecurityManager (securityManager);
        //全局对象通过安全管理者生成Subject对象
        // 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")) {
            System.out.println ("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 {
                //传入用户数据,之后的工作会交给Realm进行验证账户,密码
                currentUser.login (token);
            } catch (UnknownAccountException uae) {
                //没有这个用户
                System.out.println ("There is no user with username of " + token.getPrincipal ( ));
            } catch (IncorrectCredentialsException ice) {
                //密码不对
                System.out.println ("Password for account " + token.getPrincipal ( ) + " was incorrect!");
            } catch (LockedAccountException lae) {
                //尝试次数过多
                System.out.println ("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):
        //打印用户名
        System.out.println ("User [" + currentUser.getPrincipal ( ) + "] 登陆成功!.");

        //test a role:测试是否有schwartz这个角色
        if (currentUser.hasRole ("schwartz")) {
            System.out.println ("你拥有角色'Schwartz'");
        } else {
            //普通角色
            System.out.println ("Hello, 你不是'schwartz'这个角色");
        }

        //test a typed permission (not instance-level)测试用户是否有权限lightsaber:wield
        if (currentUser.isPermitted ("lightsaber:wield")) {
            System.out.println ("你拥有权限,'lightsaber:wield'");
        } else {
            System.out.println ("抱歉, lightsaber 仅仅 角色为 schwartz 拥有.");
        }

        //a (very powerful) Instance Level permission:
        if (currentUser.isPermitted ("winnebago:drive:eagle5")) {
            System.out.println ("你拥有权限:winnebago:drive:eagle5");
        } else {
            System.out.println ("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
        }

        //注销,销毁session
        currentUser.logout ( );
        System.out.println("用户注销了...");
        try {
            String value2 = (String) session.getAttribute ("someKey");
                System.out.println ("somekey的session值:"+value2);

        }catch (UnknownSessionException e){
            System.out.println("session在你注销后就已经销毁了!!");
        }
        //退出
        System.exit (0);
    }
}

总结:1.ini配置了用户 角色和权限 可以模拟数据库
2.加载数据到 SecurityManager 安全管理器
3.SecurityUtils设置SecurityManager
4.通过SecurityUtils获取subject
5.检查是否验证登陆,没有就把用户数据封装 UsernamePasswordToken token
6.login(token)登陆,交给realm验证账户密码等

发布了10 篇原创文章 · 获赞 6 · 访问量 356

猜你喜欢

转载自blog.csdn.net/qq_45394274/article/details/104574354