文档章节

我对shiro的初步认识

jj_soft
 jj_soft
发布于 2016/06/04 15:25
字数 928
阅读 6
收藏 0
package com.shiro;
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.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * @since 0.9 RC2
 */
public class HelloShiro {

    private static final transient Logger log = LoggerFactory.getLogger(HelloShiro.class);


    public static void main(String[] args) {

        //创建一个最简单的方法与配置Shiro SecurityManager
        //服务器、用户、角色和权限是使用简单的INI配置。
        //我们会做,通过使用一个工厂能摄取。ini文件和
        //返回一个SecurityManager实例:
        
        //使用shiro。ini文件在类路径的根
        //(文件:和url前缀负载分别从文件和url):
        //1根据配置文件获取一个shiro的的工厂类
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        //2在工厂类中获取shiro的安全管理器
        SecurityManager securityManager = factory.getInstance();
        //3把securityManager放入SecurityUtils中
        SecurityUtils.setSecurityManager(securityManager);
        //4使用SecurityUtils获取当前登录的用户
        Subject currentUser = SecurityUtils.getSubject();
        //5获取当前用户的会话状态 shiro内置的session
        Session session = currentUser.getSession();
        
        //可自行放入一些属性到session里,然后根据自己的业务逻辑进行处理
        session.setAttribute("someKey", "aValue");
        String value = (String) session.getAttribute("someKey");
        if (value.equals("aValue")) {
            log.info("Retrieved the correct value! [" + value + "]");
        }
        //6判断当前用户是否已验证身份
        if (!currentUser.isAuthenticated()) {
            System.out.println("当前用户没有登录---->");
            //7模拟创建一个登录令牌
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
            token.setRememberMe(true);
            try {
                //8进行登录操作
                //登录流程
                //currentUser.login(token);--->调用了securityManager.login(this, token)方法
                //---securityManager的login方法首先调用AuthenticatingSecurityManager的authenticate(AuthenticationToken token)方法
                //---然后AuthenticatingSecurityManager的authenticate方法调用了ModularRealmAuthenticator的doAuthenticate(AuthenticationToken authenticationToken)
                //---然后ModularRealmAuthenticator的doAuthenticate方法获取配置文件的的realm,如果配置文件没有定义realm,则默认使用SimpleAccountRealm
                //--,若配置文件配置了多个realm,则遍历这些realm,并一一调用realm里的getAuthenticationInfo方法来获取AuthenticationInfo(身份验证信息)验证当前登录用户
                //---从以上流程说明,我们可以通过自定多个realm,然后覆盖getAuthenticationInfo方法,从而达到自定义验证身份的方法
                currentUser.login(token);
                //Principal因为是object类型,所以我们在实际业务中可以自己扩展这个类
                System.out.println("用户已登录---->  用户名:"+currentUser.getPrincipal().toString());
            } 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 (AuthenticationException ae) {
            }
        }

        //9判断当前登录用户的角色---
        //从源代码可以看出,currentUser.hasRole("schwartz")---调用了securityManager.hasRole(getPrincipals(), roleIdentifier)的方法
        //再然后调用了AuthorizingRealm的hasRole(PrincipalCollection principal, String roleIdentifier)方法,
        //而AuthorizingRealm的hasRole方法会先使用getAvailableAuthorizationCache()在缓存里获取AuthorizationInfo,如果缓存里没有AuthorizationInfo
        //则默认的子类SimpleAccountRealm里获取的doGetAuthorizationInfo的方法里AuthorizationInfo(授权信息),而子类SimpleAccountRealm会在 factory.getInstance();时就把用户和角色放入一个map中,
        //也就是说我们可以通过自定义AuthorizingRealm然后覆盖doGetAuthorizationInfo方法来实现我们的自定义验证授权信息
        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)
        //10权限验证
        //从源代码可以看出currentUser.isPermitted("lightsaber:weild")---调用了securityManager.isPermitted(getPrincipals(), permission),
        //----然后调用了AuthorizingRealm的isPermitted(PrincipalCollection principals, String permission),该方法里获取默认的permissionResolver,就是权限字符的解析器
        //---然后调用了AuthorizingRealm。getAuthorizationInfo(),首先在缓存里获取AuthorizationInfo,如果没有,再从子类的SimpleAccountRealm的 doGetAuthorizationInfo去获取AuthorizationInfo
        //----也就是说,我们可以通过AuthorizingRealm类,然后实现doGetAuthenticationInfo方法,从而实现自己业务逻辑的权限验证
        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);
    }
}

 

© 著作权归作者所有

jj_soft
粉丝 1
博文 96
码字总数 74097
作品 0
广州
程序员
私信 提问
在Spring+FreeMarker框架中使用Shiro的Tag标签

目前Freemarker对Shrio的标签还不支持,不过已经有人贡献出来第三方面解决方案,如下: 1、下载shiro-freemarker-tags GitHub地址:https://github.com/jagregory/shiro-freemarker-tags 可以...

zkool
2014/01/19
7.9K
0
Could not obtain transaction-synchronized Session for current thread

重写了shiro的sessionDao 登录成功后doReadSession方法报错,理论上来说,读方法也不需要事务啊 初步怀疑是shiro配置有问题,附上配置代码

JavaSon712
2018/04/06
748
1
JFinal 整合 Shiro

最近整合JFinal和Shiro遇到的问题,希望能给你们提示与帮助。 首先,JFinal和Shiro本人都是刚刚接触,JFinal上手很快,但Shiro上手比较费劲,看了很长时间的文档。 下面说一下整合JFinal配置...

leon_rock
2013/06/02
8.3K
10
回首16,展望17。

我是一名在校的大学生,时光流逝转眼就到了该毕业的时间了,大学的四年对于我们来说却只有三年。学校的压缩式教学让我们三年学完了四年的东西,无论你学的怎样都要出去找工作。现在的我也将面...

two_people
2017/01/06
0
0
shiro 的几个问题

系统情况大概是这样的,前后台,后台为管理员,前台为普通用户。为了方便管理,系统集成了shiro。由于前台需要集成cas,于是将后台shiro与前台进行了分离。web.xml配置如下: 但是现在遇到了一...

zk461759809
2015/08/01
749
2

没有更多内容

加载失败,请刷新页面

加载更多

Less导入选项

Less 提供了CSS @import CSS规则的几个扩展,以提供更多的灵活性来处理外部文件。 语法: @import (keyword) "filename"; 以下是导入指令的相关详情: reference,使用较少的文件但不输出。 ...

凌兮洛
5分钟前
3
0
Docker下实现MySQL主从(读、写分离)同步配置

docker下实现两个(或多个)mysql容器的主、从数据库同步配置,首先要明白docker容器的相互通信关系,默认是使用的bridge模式: 也就是说,通过docker run命令创建docker容器是每个容器都有自己...

源哥L
15分钟前
8
0
一起来学Java8(三)——方法引用

在一起来学Java8(一)——函数式编程中有一个简单的函数式编程的例子: import java.util.function.Consumer;class Person { public static void sayHello(String name) { S...

猿敲月下码
34分钟前
15
0
读书笔记:深入理解ES6(十一)

第十一章 Promise与异步编程   Promise可以实现其他语言中类似Future和Deferred一样的功能,是另一种异步编程的选择,它既可以像事件和回调函数一样指定稍后执行的代码,也可以明确指示代码...

张森ZS
58分钟前
23
0
面试官,Java8 JVM内存结构变了,永久代到元空间

在文章《JVM之内存结构详解》中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化。作为面试官如果你还不知道,那么面试过程中是不是有些露怯?作为面试...

程序新视界
今天
30
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部