shiro自学总结

目录

1.介绍

1)基本功能

2)架构

3)优缺点

2.配置

1)web.xml

2)spring-context-shiro.xml

3.标签和注解

 1)标签

2)注解

4.会话和缓存

1)会话

2)缓存

5.授权和认证

1)授权

2)认证


1.介绍

 

1)基本功能

Authentication:身份认证/登录,验证用户是不是拥有相应的身份;

Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;

Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;

Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;

Web Support:Web支持,可以非常容易的集成到Web环境;

Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;

Concurrency:shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;

Testing:提供测试支持;

Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;

Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

记住一点,Shiro不会去维护用户、维护权限;这些需要我们自己去设计/提供;然后通过相应的接口注入给Shiro即可。

 

2)架构

可以看到:应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心就是Subject;其每个API的含义:

Subject:主体,代表了当前“用户”,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等;即一个抽象概念;所有Subject都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager;可以把Subject认为是一个门面;SecurityManager才是实际的执行者;

SecurityManager:安全管理器;即所有与安全有关的操作都会与SecurityManager交互;且它管理着所有Subject;可以看出它是Shiro的核心,它负责与后边介绍的其他组件进行交互,如果学习过SpringMVC,你可以把它看成DispatcherServlet前端控制器;

Realm:域,Shiro从从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源。

Subject:主体,可以看到主体可以是任何可以与应用交互的“用户”;

SecurityManager:相当于SpringMVC中的DispatcherServlet或者Struts2中的FilterDispatcher;是Shiro的心脏;所有具体的交互都通过SecurityManager进行控制;它管理着所有Subject、且负责进行认证和授权、及会话、缓存的管理。

Authenticator:认证器,负责主体认证的,这是一个扩展点,如果用户觉得Shiro默认的不好,可以自定义实现;其需要认证策略(Authentication Strategy),即什么情况下算用户认证通过了;

Authrizer:授权器,或者访问控制器,用来决定主体是否有权限进行相应的操作;即控制着用户能访问应用中的哪些功能;

Realm:可以有1个或多个Realm,可以认为是安全实体数据源,即用于获取安全实体的;可以是JDBC实现,也可以是LDAP实现,或者内存实现等等;由用户提供;注意:Shiro不知道你的用户/权限存储在哪及以何种格式存储;所以我们一般在应用中都需要实现自己的Realm;

doGetAuthenticationInfo()方法:用来验证当前登录的用户,获取认证信息

doGetAuthorizationInfo()方法:用来为当前登陆成功的用户授予权限和角色(已经登陆成功了)

SessionManager:如果写过Servlet就应该知道Session的概念,Session呢需要有人去管理它的生命周期,这个组件就是SessionManager;而Shiro并不仅仅可以用在Web环境,也可以用在如普通的JavaSE环境、EJB等环境;所有呢,Shiro就抽象了一个自己的Session来管理主体与应用之间交互的数据;这样的话,比如我们在Web环境用,刚开始是一台Web服务器;接着又上了台EJB服务器;这时想把两台服务器的会话数据放到一个地方,这个时候就可以实现自己的分布式会话(如把数据放到Memcached服务器);

SessionDAO:DAO大家都用过,数据访问对象,用于会话的CRUD,比如我们想把Session保存到数据库,那么可以实现自己的SessionDAO,通过如JDBC写到数据库;比如想把Session放到Memcached中,可以实现自己的Memcached SessionDAO;另外SessionDAO中可以使用Cache进行缓存,以提高性能;

CacheManager:缓存控制器,来管理如用户、角色、权限等的缓存的;因为这些数据基本上很少去改变,放到缓存中后可以提高访问的性能

Cryptography:密码模块,Shiro提高了一些常见的加密组件用于如密码加密/解密的。

 

3)优缺点

1、简单易懂,开源框架。

2.可以实现, 认证、授权、加密、会话管理、与Web集成、缓存

简单性,Shiro 在使用上较 Spring Security 更简单,更容易理解。

灵活性,Shiro 可运行在 Web、EJB、IoC、Google App Engine 等任何应用环境,却不依赖这些环境。而 Spring Security 只能与 Spring 一起集成使用。

Shiro 是一个强大而灵活的开源安全框架,能够非常清晰的处理认证、授权、管理会话以及密码加密。如下是它所具有的特点:

· 易于理解的 Java Security API;

· 简单的身份认证(登录),支持多种数据源(LDAP,JDBC,Kerberos,ActiveDirectory 等);

· 对角色的简单的签权(访问控制),支持细粒度的签权;

· 支持一级缓存,以提升应用程序的性能;

· 内置的基于 POJO 企业会话管理,适用于 Web 以及非 Web 的环境;

· 异构客户端会话访问;

· 非常简单的加密 API;

· 不跟任何的框架或者容器捆绑,可以独立运行。

2.配置

1)web.xml

2)spring-context-shiro.xml

web.xml中的filter-name与spring-context-shiro.xml中的bean 的id要相同。和spring-security一样,DelegatingFilterProxy是一个代理过滤器,目标过滤器是shiroFilter。而shiroFilter在配置项中是一个ShiroFilterFactoryBean工厂。其实在创建实例的时候ShiroFilterFactoryBean会创建一个SpringShiroFilter类,所以最终代理的是SpringShiroFilter。shiro与web和spring的集成写在pom.xml里

3.标签和注解

 1)标签

标签库的导入:<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>  

标签库定义在shiro-web.jar包下的META-INF/shiro.tld中定义。

1、<!-- guest  :用户没有验证时显示相应信息 ,如登录等相关信息-->

<shiro:guest>

    <a href="login.jsp">登录</a><br><br>

</shiro:guest>

2、<!-- user: 用户已经经过认证/记住我登录后 显示相应的信息 -->

<shiro:user>

    <a href="logout">登出</a><br><br>

</shiro:user>

3、<!-- authenticated 用户已经经过身份验证,但不是记住我登录的 -->

<shiro:authenticated>

    <shiro:principal />已经经过身份验证<br><br>

</shiro:authenticated>

4、<!-- 用户没有进行身份验证,记住我自动登录的属于没有进行身份验证 -->

<shiro:notAuthenticated>

    用户没有进行身份验证,记住我自动登录的属于没有进行身份验证<br><br>

</shiro:notAuthenticated>

5、principal 标签 :输出当前用户信息,通常为登录帐号信息。

Hello, <shiro:principal/>, how are you today?

6、<!-- 当前用户是否拥有该角色,有就显示相关信息 -->

<shiro:hasRole name="admin">

    <a href="admin.jsp">Admin Page</a><br><br>

</shiro:hasRole>

7、<!-- 当前用户没有相应的角色,将显示body中的信息 -->

<shiro:lacksRole name="manager">

    <shiro:principal></shiro:principal>没有manager角色<br><br>

</shiro:lacksRole>

8、<!-- 当前用户有任意一个角色将会显示body体中的内容 -->

<shiro:hasAnyRoles name="admin,user,manager">

    <shiro:principal></shiro:principal>拥有admin/user/manager中的角色<br><br>

</shiro:hasAnyRoles>

9、<!-- 当前用户有相应的权限,将显示body体中的信息 -->

<shiro:hasPermission name="customer:delete">

    <shiro:principal />拥有customer:delete权限<br><br>

</shiro:hasPermission>

10、<!-- 当前用户没有相应的权限,将显示body体中的信息 -->

<shiro:lacksPermission name="customer:delete">

    没有权限customer:delete<br><br>

</shiro:lacksPermission>

标签可以按照已有标签进行自定义添加!

2)注解

Shiro注解支持AspectJ、Spring、Google-Guice等,可根据应用进行不同的配置。

1、@ RequiresAuthentication

可以用户类/属性/方法,用于表明当前用户需是经过认证的用户。

@RequiresAuthentication  

public void updateAccount(Account userAccount) {  

    //this method will only be invoked by a   

    //Subject that is guaranteed authenticated  

    ...  

}  

使用这个注解之前,需要先在spring-mvc.xml加入一段代码(一定要写在最先加载的xml中,写在后面加载的xml中也不起作用),lifecycleBeanPostProcessor和securityManager是在shiro配置文件中定义好的。

2、@ RequiresGuest

表明该用户需为”guest”用户

3、@ RequiresPermissions

当前用户需拥有制定权限

4、@RequiresRoles

当前用户需拥有制定角色

@RequiresRoles(value={“admin”, “user”}, logical= Logical.AND)  表示需要admin和user

5、@ RequiresUser

当前用户需为已认证用户或已记住用户

4.会话和缓存

1)会话

shiro提供了一个完整的企业级会话管理解决方案,不再依赖web容器。可以在web和非web环境下使用。

shiro的session特性:

基于POJO/J2SE:shiro中session相关的类都是基于接口实现的简单的java对象(POJO),兼容所有java对象的配置方式,扩展也更方便,完全可以定制自己的会话管理功能 。

简单灵活的会话存储/持久化:因为shiro中的session对象是基于简单的java对象的,所以你可以将session存储在任何地方,例如,文件,各种数据库,内存中等。

容器无关的集群功能:shiro中的session可以很容易的集成第三方的缓存产品完成集群的功能。例如,Ehcache + Terracotta, Coherence, GigaSpaces等。你可以很容易的实现会话集群而无需关注底层的容器实现。

异构客户端的访问:可以实现web中的session和非web项目中的session共享。

会话事件监听:提供对对session整个生命周期的监听。

保存主机地址:在会话开始session会存用户的ip地址和主机名,以此可以判断用户的位置。

会话失效/过期的支持:用户长时间处于不活跃状态可以使会话过期,调用touch()方法,可以主动更新最后访问时间,让会话处于活跃状态。

透明的Web支持:shiro全面支持Servlet2.5中的session规范。这意味着你可以将你现有的web程序改为shiro会话,而无需修改代码。

单点登录的支持:shiro session基于普通java对象,使得它更容易存储和共享,可以实现跨应用程序共享。可以根据共享的会话,来保证认证状态到另一个程序。从而实现单点登录。

public interface Session {

    //类似于HttpSession, 定义了一些标准的session属性与操作,

    //包括Session唯一标识、会话超时时间、会话开始时间、最后访问时间、主机IP、停止会话、通过attribute绑定、删除、数据等

}

//Session管理器,负责创建、持久化和删除会话实例及其生命周期。

public interface SessionManager{

    Session start(SessionContext context); //创建一个新的会话

    //根据SessionKey获取会话,如果没有找到会话,返回null.

    //如果找到一个无效会话(过期或停止),抛出SessionException

    Session getSession(SessionKey key) throws SessionException;

}

public interface SessionDAO {

    //将一个新的Session记录保存到EIS(关系型数据库、文件系统、持久缓存,等等)

    Serializable create(Session session);

    //从EIS中检索Session

    Session readSession(Serializable sessionId) throws UnknownSessionException;

    //更新Session信息

    void update(Session session) throws UnknownSessionException;

    //删除Session,如果EIS中没有该Session,什么都不做

    void delete(Session session);

    //返回全部存活的Session

    Collection<Session> getActiveSessions();

}

shiro通过这三个接口实现会话管理。

Shiro中一切的操作都是通过SecurityManager来实现的。实际上SecurityManager继承了 SessionManager,实际操作也是通过SessionsSecurityManager来进行的。查看SessionsSecurityManager代码,可以看到SecurityManager是委托给一个可用的SessionManager来执行,默认使用DefaultSessionManager。实际上Shiro只为SessionManager提供了 DefaultSessionManager 一个可用的实现类。

2)缓存

每一次给用户授权时,都是通过realm从数据库中查询权限,为了避免频繁的查询数据库,shiro给我们提供了缓存的能力。

用户认证通过后:

第一次授权:通过realm从数据库中查询

第二次授权:直接从缓存中查询

引入包

1. shiro-ehcache.jar

2. ehcache-core.jar

jeesite中,cache和session结合到一起:

 

5.授权和认证

1)授权

授权有三个核心元素:权限,角色,用户。

1、权限

权限的粗细粒度:粗粒度权限管理,对资源类型的权限管理。资源类型比如:菜单、url连接、用户添加页面、用户信息、类方法、页面中按钮。

粗粒度权限管理比如:超级管理员可以访问户添加页面、用户信息等全部页面。

部门管理员可以访问用户信息页面包括 页面中所有按钮。

细粒度权限管理,对资源实例的权限管理。资源实例就资源类型的具体化。细粒度权限管理就是数据级别的权限管理。

Shiro权限声明通常是使用以冒号分隔的表达式。就像前文所讲,一个权限表达式可以清晰的指定资源类型,允许的操作,可访问的数据。同时,Shiro权限表达式支持简单的通配符,可以更加灵活的进行权限设置。

下面以实例来说明权限表达式。

可查询用户数据

User:view

可查询或编辑用户数据

User:view,edit

可对用户数据进行所有操作

User:* 或 user

可编辑id为123的用户数据

User:edit:123

2、角色

Shiro支持两种角色模式:

1、传统角色:一个角色代表着一系列的操作,当需要对某一操作进行授权验证时,只需判断是否是该角色即可。这种角色权限相对简单、模糊,不利于扩展。

2、权限角色:一个角色拥有一个权限的集合。授权验证时,需要判断当前角色是否拥有该权限。这种角色权限可以对该角色进行详细的权限描述,适合更复杂的权限设计。

下面将详细描述对两种角色模式的授权实现。oa:oaNotify:view,oa:oaNotify:edit

3、授权的实现

Shiro支持三种方式实现授权过程:

编码实现

注解实现

JSP Taglig实现

1、基于传统角色授权实现

验证用户是否拥有某个角色:  SecurityUtils.getSubject();

相关验证方法如下:

Subject方法                                                           描述

hasRole(String roleName)                                    当用户拥有指定角色时,返回true

hasRoles(List<String> roleNames)                       按照列表顺序返回相应的一个boolean值数组

hasAllRoles(Collection<String> roleNames)         如果用户拥有所有指定角色时,返回true

2、基于权限对象的实现:SecurityUtils.getSubject();

相关方法如下:

Subject方法                                                                 描述

isPermitted(Permission p)                                           Subject拥有制定权限时,返回treu

isPermitted(List<Permission> perms)                         返回对应权限的boolean数组

isPermittedAll(Collection<Permission> perms)           Subject拥有所有制定权限时,返回true

2)认证

1、创建token令牌,token中有用户提交的认证信息即账号和密码

2、执行subject.login(token),最终由securityManager通过Authenticator进行认证

3、Authenticator的实现ModularRealmAuthenticator调用realm从ini配置文件取用户真实的账号和密码,这里使用的是IniRealm(shiro自带)

4、IniRealm先根据token中的账号去ini中找该账号,如果找不到则给ModularRealmAuthenticator返回null,如果找到则匹配密码,匹配密码成功则认证通过。

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值