Shiro概念篇(一)跟我一起学shiro

​What is Apache Shiro?

此文未排版,欢迎点击链接阅读原文,原文链接

官方的回答翻译过来就是,shiro是一个权限框架,提供身份认证、授权、加密、session管理

What can Apache Shiro do?

Shiro的目标是成为最安全使用最简单的安全框架,提供的功能如下:

任何地方都可以最容易理解的Java安全api,类和接口都有非常直观易理解的名字,任何配置都是可插拔的,并且有很好的默认配置

支持跨多个数据源(即realms)的登录身份验证

支持角色或者更细微控制的权限进行授权控制,也可以使用可插拔的数据源

为提高应用程序性能,支持一级缓存

基于pojo的企业session会话管理,可同时用户web和非web环境,也可以用在单点登录sso,集群,分布式会话管理

可以被多种客户端使用,不用强制使用httpsession或者有状态的session对象,不用绑定特定的环境使用,不管部署环境是什么都可以共享会话状态(flash,c#,web,java web)

简单的企业会话单点登录支持,如果跨越多个平台,用户的身份验证信息也可以共享。即一次登录任何一个应用程序,其他应用程序都可以识别该登录

使用最简单可用的加密api来保护数据,比java提供的密码和hash更强大

一个非常健壮的低配置web框架,可以保护任何的url和资源,自动处理登录和退出,记住我等等功能

所需要的依赖极少,单独的配置需要一个slf4j-api和一个slf4j绑定的jar包,web配置需要一个commons-beanutils-core.jar,当有需要的时候可以基于依赖项配置Ehcache缓存,quartz会话验证,Spring依赖项注入等

概述

三部分组成:Subject,SecurityManager ,Realms
Subject:主题,绑定到SecurityManager。在本质上是当前正在执行的用户的安全视图
SecurityManager:Shiro核心,充当一种伞的对象,该对象可以协调内部组件,这些内部组件形成一个对象图,但是可以不必理会,大部分操作都是相当于用户不可见的,即幕后的操作
Realms:Shiro与应用程序通信的桥梁,一般身份验证,授权都在此,在配置Shiro时,至少配置一个Realm来用于身份验证和授权;Shiro提供了开箱即用的Realm,可以连接到许多特定的数据源(LDAP),JDBC,文本配置源ini和属性文件等,如果默认的Realm不能满足我们的需求,我们可以自己实现一个Realm,自定义自己的需求

详细架构图

Authentication

Authentication
Subject Based:shiro中几乎所有的操作都基于当前正在登录执行的用户,即Subject主题,而且可以在我们代码的任何地方来进行检索subject使用,这样更容易让我们在应用程序中更容易理解和使用shiro

Simple Method Call :我理解的是单个方法调用,身份验证过程是单个方法的调用,只使用一个方法的接口调用可以保证在我们的应用程序代码中保持api的简洁和代码的干净,从而节省时间和精力

Rich Exception Hierarchy :丰富的异常结构,Shiro提供了丰富的异常层次结构,当登录失败时可以返回更加详细的异常信息,这种丰富的异常结构可以帮助我们更容易的判断代码与身份验证相关的代码bug或者客户服务相关的问题,另外,这种丰富性可以帮助我们创建更复杂的身份验证功能

Remember Me’ built in:记住我功能:shiro api标准是如果用户返回当前应用程序,能够记住我,这样可以使用最少的开发工作带给用户更好的体验

Pluggable data sources:可插入数据源,Shiro使用可插入数据源称为Realm来连接到安全数据源,例如(LDAP and Active Directory.)为了帮助我们集成避免自己构建和维护,shiro已经集成了(LDAP, Active Directory, and JDBC)如果有需要,我们可以创建自己的realm来支持特殊的功能

Login with one or more realms:使用shiro,可以轻松的对一个或多个领域的用户进行身份验证,并返回用户的统一视图,另外还可以使用shiro的身份验证策略自定义身份验证过程,这些策略可以在配置文件中配置不需修改源码,减少了复杂性和工作量

前提条件

Subject :主题,与应用程序交互的对象,可以是一个人,一个进程

Principals: 主题Subject的主要识别属性

Credentials: 被用来验证身份的秘密数据,可以是密码,含有生物特征的数据,x509证书

Realms:特定的安全Dao,数据访问对象,与后段数据源对话的软件组件,如果LDAP中有用户名和密码,那么LDAP Realm与LDAP通信,来完成将要完成的工作,即Realms中实现的自定义代码

使用Java验证

收集主题的身份和证书加密信息

提交身份和证书加密信息到身份验证系统

返回验证通过,重试验证或拒绝验证

// 获取需要提交的subjec和验证证书
//Example using most common scenario:
//String username and password. Acquire in
//system-specific manner (HTTP request, GUI, etc)
UsernamePasswordToken token = new UsernamePasswordToken( username, password );

//”Remember Me” built-in, just do this:
token.setRememberMe(true);
// 提交我们的验证信息
//With most of Shiro, you’ll always want to make sure you’re working with the currently
//executing user, referred to as the subject
Subject currentUser = SecurityUtils.getSubject();

//Authenticate the subject by passing
//the user name and password token
//into the login method
currentUser.login(token);
// 返回验证结果
try {
currentUser.login(token);
} catch ( UnknownAccountException uae ) { …
} catch ( IncorrectCredentialsException ice ) { …
} catch ( LockedAccountException lae ) { …
} catch ( ExcessiveAttemptsException eae ) { …
} … your own …
} catch ( AuthenticationException ae ) {
//unexpected error?
}
//No problems, show authenticated view…
RememberMe Support

Shiro支持两个方法:isRemembered() and isAuthenticated()

Subject被记住不意味着已经被验证

在Shiro中,记住的主题并不是被验证的主题,进行isAuthenticated是一个更加严格的检查,身份验证是一个验证是否是我们所需要该身份的验证的一个过程。而记住我功能只是使系统知道我可能是谁,但是却无法绝对保证我是当前系统访问的用户,主题通过验证之后,就不再仅仅是记住我,相应的也会记住验证信息,即Subject在当前会话中已经通过验证

注销

在Shiro中使用一个注销方法即可注销身份等信息

currentUser.logout(); //removes all identifying information and invalidates their session too.
在提交注销请求之后,Shiro会在Subject实例中删除一切相关当前登录用户的信息并关闭当前用户会话,如果在web环境中使用了记住我的功能,Shiro还会从浏览器中删除rememberMe cookie
Authorization

Q:
什么是授权三要素

A:
权限、角色、用户

权限定义

权限是安全策略最基本的级别,功能的声明,权限在应用程序中代表了可以做的相关操作,例如crud,我们要理解的是权限不能告诉我们谁可以执行操作,而是对这些操作的描述,例如,权限不会告诉我拥有test.txt这个文件crud的权限,而是会告诉我们test.txt有crud这四个权限

权限粒度级别

我们这里有一本请求操作记录

Resource level:最广泛的权限级别,用户可以编辑操作记录
Instance level:实例级别,用户可以编辑这本操作记录中admin的操作记录
Attribute level:属性级别,用户可以编辑admin用户操作记录中请求地址这个字段的值
角色定义

角色可以说是权限的集合,简化权限与用户的管理,这样的话可以给用户分配角色,而不是直接分配权限给用户;例如一个群组里有管理员和普通成员的角色

隐式角色:应用程序默认了一组权限,用户默认拥有这些权限,而不用为角色明确分配权限在把角色赋予给用户
显式角色:显示角色具有显示分配权限,因此是显示的权限集合。显示角色可以动态添加删除修改,易于管理,减少了应用程序的维护,在运行时修改用户角色信息,在进行授权检查时始终保持最新值,不必强制强迫用户注销并重新登录获取新权限

用户定义

Shiro中,用户即Subject主题
最后,Realm与数据源进行通信,返回告诉Shiro角色权限是否存在,而我们可以自定义授权来返回角色权限是否存在

使用Shiro在Java中进行授权

角色检查
//get the current Subject
Subject currentUser = SecurityUtils.getSubject();

if (currentUser.hasRole(“administrator”)) {
//show a special button‏
} else {
//don’t show the button?)‏
}

权限检查
Subject currentUser = SecurityUtils.getSubject();

Permission printPermission = new PrinterPermission(“laserjet3000n”,“print”);

If (currentUser.isPermitted(printPermission)) {
//do one thing (show the print button?)‏
} else {
//don’t show the button?
}
基于字符串的权限检查
String perm = “printer:print:laserjet4400n”;

if(currentUser.isPermitted(perm)){
//show the print button?
} else {
//don’t show the button?
}

使用注解授权

权限检查

//Will throw an AuthorizationException if none
//of the caller’s roles imply the Account
//‘create’ permission
@RequiresPermissions(“account:create”)‏
public void openAccount( Account acct ) {
//create the account
}
角色检查
//Throws an AuthorizationException if the caller
//doesn’t have the ‘teller’ role:
@RequiresRoles( “teller” )
public void openAccount( Account acct ) {
//do something in here that only a teller
//should do
}
JSP中taglib
<%@ taglib prefix=“shiro” uri=http://shiro.apache.org/tags %>

Click here to manage users No user management for you!

Session Management

using session

Subject currentUser = SecurityUtils.getSubject();

Session session = currentUser.getSession();
session.setAttribute( “someKey”, someValue);

currentUser.getSessiom()实际调用的是currentUser.getSession(true)
Subject.getSession(boolean create) 方法实际与HttpServletRequest.getSession(boolean create)方法相同
1、 如果Subject已经有一个session,则参数忽略并返回session
2、 如果Subject没有session,参数为true,则将创建一个并返回新的会话
3、 如果Subject没有session,参数为false,则将不会创建新会话返回session为null返回该会话
getSession()可以在任何应用程序使用,甚至与非web应用

SessionManager

可以管理应用程序中所有主题的创建、删除、销毁、验证,维护了顶级组件SecurityManager,SecurityManager默认实现DefaultSecurityManager,开箱即用,DefaultSecurityManager实现了企业级会话管理功能,例如会话管理,清除;
SessionManager可以像管理SecurityManager一样,SessionManager可以通过getSessionManager/setSessionManager来获取设置他们
例如使用shiro.ini配置
[main]

sessionManager = com.foo.my.SessionManagerImplementation
securityManager.sessionManager = $sessionManager
Shiro的SessionManager实现的是高度可配置可定制的,能满足大多数需求

Session Timeout

Shiro的SessionManager默认实现30分钟超时,也就是说,任何Session创建的内容在lastAccessedTime 30分钟或更长时间内保持空闲状态(未使用/未更新),则该Session将被视为过期,不能被使用
可以通过设置SessionManager的globalSessionTimeout来更改Session过期时间

shiro.ini中设置超时时间,此处设置1小时过期,单位是毫秒

[main]

3,600,000 milliseconds = 1 hour

securityManager.sessionManager.globalSessionTimeout = 3600000

Session Listeners

Session监听器,实现Session监听,可以让我们在重点关注的会话发生时作出反应,可以通过实现Session Listeners接口或者SessionListenerAdapter作出反应,由于SessionManager的sessionListeners属性是个集合,所以我们可以像配置其他监听器一样来配置一个或者多个监听器
在shiro.ini中配置
[main]

aSessionListener = com.foo.my.SessionListener
anotherSessionListener = com.foo.my.OtherSessionListener

securityManager.sessionManager.sessionListeners = $aSessionListener, $anotherSessionListener, etc.

SessionListeners在任何事件发生时都会收到通知(不仅特定的会话)

Session Storage

每当我们创建一个新会话或者更新时,其数据都要保存在一定位置,当Session失效或者长时间未使用时,需要将其从存储删除,SessionManager将crud的操作委托给了一个内部组件SessionDao,SessionDao可以实现此接口与任何的数据存储进行通信。也就是说数据可以保留在内存,系统,关系数据库,非关系数据库,或者任何的其他位置。我们可以实现自己的SessionDao来作为默认实现Shiro.ini配置为

[main]

sessionDAO = com.foo.my.SessionDAO
securityManager.sessionManager.sessionDAO = $sessionDAO
上述这种配置只在本机服务器生效,在web应用程序中是不行的,会使用默认的会话管理器,不会使用配置的SessionDao,所以要改为下面配置,先配置SessionManager
[main]

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager

Configure a SessionDAO and then set it:

securityManager.sessionManager.sessionDAO = $sessionDAO
SessionDao默认的是内存存储,但是大多数生产环境都是使用配置Ehcache支持

EHCache SessionDao

默认情况下,Shiro未启用EHCache,如果我们不准备自己实现SessionDao,则推荐我们使用SessionManagement启用EHCache支持。EHCache SessionDao 将数据保存在内存中,如果内存受到限制,支持向磁盘溢出,这个设计可以确保在生产环境中不回随机的丢失session;

启用EHCache非常简单,确保jar包已经引入《shiro-ehcache-.jar》,下面是在Shiro.ini配置
[main]

sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
securityManager.sessionManager.sessionDAO = $sessionDAO

cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
securityManager.cacheManager = $cacheManager
Web应用程序不支持基于Servlet容器的SessionManager SessionDao,如果要在Web应用程序中使用EHCache,按照上面配置本地Sessionmanager
EHCache缓存设置
ehcache.xml

我们在更改自定义ehcache.xml文件内容时,有两个属性是不要更改的
overflowToDisk=“true” -这样可以确保如果进程内存用完了,会话也不会丢失并且可以序列化到磁盘上
eternal=“true”-确保缓存条目(会话实例)永远不会被缓存自动过期或删除。这是必需的,因为Shiro会根据计划的过程进行自己的验证,如果将其关闭,则缓存可能会在Shiro不了解的情况下删除Sessions,这可能会导致问题

Cryptography

简介

通过加密或生成无用信息来混淆正确数据,来达到访问数据被保护的目的

两个方面

1、 公钥私钥加密

2、不可逆的hash

支持的hash算法

md5,SHA-256,SHA1

Apache Shiro Cryptography Features

posted @   微信公众号-醉鱼Java  阅读(89)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
点击右上角即可分享
微信分享提示