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);
}
}

我对shiro的初步认识的更多相关文章

  1. 2521-Shiro系列-基本使用

    在springboot中使用SHiro作为安全框架,非常简单,灵活性也比较高 在springboot中使用Shiro不用像官网教程那样,官网是将配置文件写在INI文件和XML配置中 springboo ...

  2. shiro权限控制(一):shiro介绍以及整合SSM框架

    shiro安全框架是目前为止作为登录注册最常用的框架,因为它十分的强大简单,提供了认证.授权.加密和会话管理等功能 . shiro能做什么? 认证:验证用户的身份 授权:对用户执行访问控制:判断用户是 ...

  3. 记录心得-shiro框架demo示例

    从懵懂到了解,再到熟悉,是一个进步的过程! 先撸代码,跑起来看效果,再做详细的介绍,开始干活! 1,先列出工程目录结构,自己需要创建对应层级的程序和相关配置文件. 2,导入maven依赖的jar包.打 ...

  4. 【shiro】(5)---基于Shiro的权限管理

    基于Shiro的权限管理项目搭建 前面写了四篇有关权限的文章,算是这篇文章的铺垫了.这篇文章采用 开发环境           JDK1.8          Eclipse          Mav ...

  5. Shiro+JWT+Spring Boot Restful简易教程

    序言 我也是半路出家的人,如果大家有什么好的意见或批评,请务必issue下. 项目地址:https://github.com/Smith-Cruise/Spring-Boot-Shiro . 如果想要 ...

  6. 从零搭建java后台管理系统(一)框架初步搭建

    框架搭建 一.初步设想,使用springboot,框架打算用到依赖 spring web,devTools,mysql,Aspect,Redis,Lombok,Freemark,Shiro,Rabbi ...

  7. Springboot + Vue + shiro 实现前后端分离、权限控制

    本文总结自实习中对项目对重构.原先项目采用Springboot+freemarker模版,开发过程中觉得前端逻辑写的实在恶心,后端Controller层还必须返回Freemarker模版的ModelA ...

  8. Shiro的认证原理(Subject#login的背后故事)

    登录操作一般都是我们触发的: Subject subject = SecurityUtils.getSubject(); AuthenticationToken authenticationToken ...

  9. shiro小记

    今天主要看了Shiro的认证,授权功能初步了解了一下,其他的功能用的不多,之后再看. 先说一下Shiro的三个核心概念: 1.Subject: 代表当前正在执行操作的用户,但Subject代表的可以是 ...

随机推荐

  1. 【转】Microsoft .Net Remoting 之.Net Remoting基础篇

    .Net Remoting基础篇 一.Remoting基础 什么是Remoting,简而言之,我们可以将其看作是一种分布式处理方式.从微软的产品角度来看,可以说Remoting就是DCOM的一种升级, ...

  2. 【转】MFC CreateFont 用法

    中国人自古就有自右至左.从上到下书写汉字的习惯.而当我们在自己所编写的应用程序中使用输出函数输出的总是自左至右的横排文字.有没有可能在我们的应用程序中实现竖写汉字的效果呢?笔者偶然发现了一种利用VC实 ...

  3. 支付宝(移动支付)服务端java版

    所需支付宝jar包: sdk2-2.0.jar(点击下载) 工具类目录结构:   点击下载 商户信息已经公钥私钥的配置(公钥私钥的生成与支付宝商户平台配置请看官方文档:https://doc.open ...

  4. 微信支付(公众号支付APIJS、app支付)服务端统一下单接口java版

    一.微信公众号支付APIJS: 要完整的实现微信支付功能,需要前后端一起实现,还需要微信商户平台的配置.这里只是涉及服务端的代码. jar包:pom.xml <!-- ↓↓↓↓↓↓↓↓ 支付相关 ...

  5. 如何查看linux命令源代码

    如何查看linux命令源代码 用linux一段时间了,有时候想看看ls.cat.more等命令的源代码,在下载的内核源码中用cscope没能找到,在网上搜索了一下,将方 法总结如下: 以搜索ls命令源 ...

  6. jquery获取点击控件的绝对位置简单实例

    在使用jquery的过程中,想取得当前点击input的绝对位置而去显示一个div,jquery本身提供offset和position这个两个方法,但position官方解释是relative to t ...

  7. 如何在 React Native 中写一个自定义模块

    https://my.oschina.net/jpushtech/blog/983230

  8. oracle客户端免安装配置、64位机器PL/SQL和VS自带的IIS连接问题

    一.oracle客户端免安装配置 1.到oracle官网下载Oracle InstantClient, 把它解压缩到单独目录,例如C:\OracleClient,2. 添加环境变量 ORACLE_HO ...

  9. 2.1 C语言下的位运算

    位运算符: 注:运算量仅仅能为整型和字符型数据,不能是实数型的数据. 当进行&运算时:0&1=0.1&0=0:1&1=1:0&0=0: 当进行|运算时:0|1= ...

  10. HDU - 2089 不要62 (暴力或数位DP)

    Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer). 杭州交通管理局常常会扩充一些的士车牌照.新近出来一个好消息.以后上牌照,不再含有不吉利的数字了.这样一来.就能够消除个别 ...