生活坏到一定程度就会好起来,因为它无法更坏,努力过后,才知道许多事情,坚持坚持,就过来了
Apache Shiro的设计目标就是用直观且易于使用的方式,来简化应用的安全性,Shiro的核心设计是基于在某人(或某物)与应用程序交互的上下文中的
软件应用经常是基于用户故事设计的,也就是说基于用户与软件交互的方式来设计用户界面或服务API,比如在用户登录后给用户展示一个个人信息按钮,用户未登录时展示一个登录按钮。应用程序的代码都是用于满足用户的需求的,即使这个所谓的“用户”是另一个软件系统
Shiro在自己的设计中体现了这些概念,实际上,Apache Shiro在任何应用程序中都保持直观和易于使用的特点
Subject:正如之前提到的,Subject是当前执行的用户所拥有的特定于安全的视图,“User”的概念经常和人绑定,而Subject可以使人,也可以是第三方服务,等等与软件交互的任何事务。Subject实例都绑定到SecurityManager,与Subject交互时,这些交互转化为与SecurityManager的特定于Subject的交互。
SecurityManager:SecurityManager是Shiro体系结构的核心,它协调其内部安全组件,形成一个对象图。一旦SecurityManager和它的内部对象图配置完成,通常就不在需要和SecurityManager打交道,开发人员更多的是和Subject 的 API 打交道。之后会详细介绍SecurityManager的细节内容,需要注意的是,Subject上的所有操作,背后都是SecurityManager在进行工作的
Realms
:Realms是Shiro和应用安全数据的桥梁,当需要与用户帐户安全相关的数据进行实际交互以执行身份验证(登录)和授权(访问控制)时,Shiro将会从事先配置好的Realms中获取数据。
Realms相当于安全方面的DAO,它封装了与数据源的连接等细节,为Shiro提供需要的数据。在配置Shiro时,必须至少配置一个Realm用于认证和授权,也就是说,SecurityManager至少需要一个Realm
Shiro提供了一些开箱即用的Realms,来连接各个数据源,如LDAP,关系型数据库,文本文件如INI配置文件等等,如果默认的Realm不能满足需求,也可以实现自己的Realm来自定义数据源
与其他内部组件一样,Shiro的SecurityManager从Realms获取以Subject实例表示的身份数据
下图展示了Shiro的具体核心架构
Subject——org.apache.shiro.subject.Subject
特定于当前与软件交互的实体的安全视图
SecurityManager——org.apache.shiro.mgt.SecurityManager
Shiro架构的核心,管理并协调各个组件共同完成安全工作,它还管理每个应用程序用户的Shiro视图,因此它知道如何为每个用户执行安全操作。
Authenticator——org.apache.shiro.authc.Authenticator
Authenticator是负责认证的组件,当用户尝试登录时,登录是由Authenticator来执行的,Authenticator将会从Realms取出用户信息,来和用户提供的登录信息进行比对
Authenticator Strategy——org.apache.shiro.authc.pam.AuthenticationStrategy
如果超过一个Realm被配置了,这个AuthenticationStrategy将会协调这些Realms来决定认证操作是否成功,比如,认证成功是需要所有的Realms都认证成功,还是仅仅一个Realm成功
Authorizer——org.apache.shiro.authz.Authorizer
Authorizer是负责访问控制的组件,换句话说,它负责检测用户是否有执行某个操作的权限。和Authenticator一样,Authorizer也从多个Realms数据源中获取用户的角色信息和权限信息,通过这些信息来判断用户是否可以执行某个操作
SessionManager——org.apache.shiro.session.mgt.SessionManager
注意不是SecurityManager,SessionManager负责创建和管理用户的Session周期。在安全框架中,Shiro提供了一个独有的特性,Shiro可以在任何环境中管理用户会话,即使实在非Web/Servlet和非EJB容器环境中,默认情况下,Shiro将会使用已有的会话机制,如Servlet容器,如果没有,Shiro将会使用内建的企业会话管理机制来管理会话。通过SessionDao,我们可以使用任何数据源来持久化Session
SessionDAO——org.apache.shiro.session.mgt.eis.SessionDAO
SessionDAO代表SessionManager执行会话持久性(CRUD)操作。它允许将任何数据存储插入到Session Management基础结构中
CacheManager——org.apache.shiro.cache.CacheManager
CacheManager负责创建Shiro中的其他组件的Cache实例并管理其生命周期,因为Shiro需要访问各种数据源来进行认证,授权和会话管理,缓存一直是框架中的一流架构特性,可以在使用这些数据源时提高性能,任何现代的开源或者企业缓存产品都可以接入Shiro中
Cryptography——org.apache.shiro.crypto.*
Shiro的crypto包包含了易于使用和理解的常见加密算法实现。使用过Java自带的加密库的人都应该知道它很难使用,Shiro提供的加密API简化了复杂的Java机制,让加密更便于使用
Realms——org.apache.shiro.realm.Realm
正如前面提到的,Realms是Shiro和应用程序数据的桥梁,当需要执行认证和授权时,Shiro会从至少一个Realm中寻找用户信息,应用程序中可以配置许多个Realm,Shiro会在必要时协调这些Realm
Shiro的API提倡以Subject为中心的编程方式,因此大多数的开发者很少会和SecurityManager直接接触,但是,仍然有必要去了解SecurityManager如何进行工作,尤其是为应用程序配置SecurityManager的时候
SecurityManager主要负责执行安全操作和管理所有应用程序用户的状态,在Shiro的默认视线中,它包括以下功能:
认证
授权
会话管理
缓存管理
协调Realm
事件传播
“记住我”服务
创建Subject
登录等等功能
但是在单个组件中要管理的功能太多了。而且,如果所有的东西都集中到一个实现类中,那么使这些东西变得灵活和可定制将是非常困难的。为了简化配置,让配置变得灵活,Shiro进行了高度的模块化实现,即SecurityManager的实现更多是扮演了一个轻量级的容器组件,将所有的行为委托给它拥有的组件
当组件执行它们的逻辑的时候,SecurityManager知道在何时,如何去协调这些组件以达到正确的行为。SecurityManager的实现和它的组件都是兼容JavaBean的,也就是说,可以通过JavaBean的方式来配置它们,如Spring等等
pom.xml的文件依赖
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.2.2
org.thymeleaf.extras
thymeleaf-extras-shiro
2.0.0
com.alibaba
druid
1.2.12
log4j
log4j
1.2.14
mysql
mysql-connector-java
1.2.17
org.apache.shiro
shiro-spring
1.9.1
org.thymeleaf
thymeleaf-spring5
org.thymeleaf.extras
thymeleaf-extras-java8time
3.0.4.RELEASE
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# =============================================================================
# Quickstart INI Realm configuration
#
# For those that might not understand the references in this file, the
# definitions are all based on the classic Mel Brooks' film "Spaceballs". ;)
# =============================================================================
# -----------------------------------------------------------------------------
# Users and their assigned roles
#
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setUserDefinitions JavaDoc
# -----------------------------------------------------------------------------
[users]
# user 'root' with password 'secret' and the 'admin' role
root = secret, admin
# user 'guest' with the password 'guest' and the 'guest' role
guest = guest, guest
# user 'presidentskroob' with password '12345' ("That's the same combination on
# my luggage!!!" ;)), and role 'president'
presidentskroob = 12345, president
# user 'darkhelmet' with password 'ludicrousspeed' and roles 'darklord' and 'schwartz'
darkhelmet = ludicrousspeed, darklord, schwartz
# user 'lonestarr' with password 'vespa' and roles 'goodguy' and 'schwartz'
lonestarr = vespa, goodguy, schwartz
# -----------------------------------------------------------------------------
# Roles with assigned permissions
#
# Each line conforms to the format defined in the
# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc
# -----------------------------------------------------------------------------
[roles]
# 'admin' role has all permissions, indicated by the wildcard '*'
admin = *
# The 'schwartz' role can do anything (*) with any lightsaber:
schwartz = lightsaber:*
# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with
# license plate 'eagle5' (instance specific id)
goodguy = winnebago:drive:eagle5