Все еще думаете, что Широ сложный (Часть 1)?

задняя часть
Все еще думаете, что Широ сложный (Часть 1)?

Это пятый день моего участия в августовском испытании обновлений, подробности о мероприятии:Испытание августовского обновления

1. Обзор Широ

1.1 Управление разрешениями

1.1.1. Управление правами

В принципе, системы с участием пользователей должны управляться с разрешениями.Управление разрешениями относится к категории системной безопасности, и реализовано управление разрешениями.对用户访问系统的控制, в соответствии с правилами безопасности или политиками безопасности, пользователи могут получить доступ и могут получить доступ только к своим авторизованным ресурсам.

Управление разрешениями включает пользователей身份认证а также授权две части, сокращенно认证授权. Для ресурсов, которым требуется управление доступом, пользователи должны сначала пройти аутентификацию личности.После прохождения аутентификации пользователи могут получить доступ к ресурсам только после того, как у них появятся права доступа к ресурсам.

1.1.2, аутентификация личности

    身份认证, — это процесс определения того, является ли пользователь законным пользователем. Наиболее часто используемый простой метод аутентификации заключается в том, что система проверяет, соответствуют ли имя пользователя и пароль, введенные пользователем, имени пользователя и паролю, хранящимся в системе, чтобы определить, верна ли личность пользователя. Для таких систем, как отпечатки пальцев, покажите отпечатки пальцев; для таких систем, как аппаратные ключи, вам необходимо провести картой.

1.1.3. Авторизация

    授权,即访问控制, который определяет, кто может получить доступ к каким ресурсам. После аутентификации субъекту необходимо назначить разрешения на доступ к ресурсам системы.Некоторые ресурсы не могут быть доступны без разрешения.

2.1 Что такое сиро

image-20200520220106539     Апачи Широ™это мощная и простая в использовании среда безопасности Java, которая выполняет аутентификацию, авторизацию, криптографию и управление сеансами.С помощью простого для понимания API Shiro вы можете быстро и легко защитить любое приложение - от самых маленьких мобильных приложений до самых больших веб-приложений и корпоративных приложений.

Apache Shiro - это основа безопасности для Java. Широ может легко развить достаточно хорошее применение, которое можно использовать не только в среде Javase, но и в среде Javaee. Широ может помочь нам: аутентификация, авторизация, шифрование, управление сеансом, интеграцию с веб-сайтом, кэшированием и т. Д.

2.2 Зачем изучать Широ

  1. Поскольку shiro извлекает функции, связанные с аутентификацией безопасности, для формирования структуры, использование shiro позволяет быстро завершить разработку таких функций, как аутентификация и авторизация, и снизить системные затраты.
  2. Shiro широко используется. Shiro может работать в веб-приложениях, не-веб-приложениях и кластерных распределенных приложениях. Все больше и больше пользователей начинают использовать shiro.

В области Java Spring Security (ранее Acegi) также является инфраструктурой управления правами с открытым исходным кодом, но Spring Security полагается на Spring для запуска, в то время как shiro относительно независима.Основная причина в том, что shiro прост и гибок в использовании, поэтому больше и больше пользователей выбирают сиро сейчас. .

2.3 Основные функции

image-20200927182532297

  1. Authentication

Аутентификация личности/логин, чтобы проверить, имеет ли пользователь соответствующую личность;

  1. Authorization

Авторизация, то есть проверка разрешения, проверяет, имеет ли аутентифицированный пользователь определенное разрешение, то есть оценивает, может ли пользователь что-то сделать, например: проверяет, имеет ли определенный пользователь определенную роль. Или мелкозернистый, чтобы проверить, есть ли у пользователя определенное разрешение на определенный ресурс;

  1. SessionManager

Управление сессией, то есть после того, как пользователь входит в систему, это сеанс, и перед выходом все его информация находится на сеансе; сеанс может быть в общей среде Javase или веб-среда;

  1. Cryptography

Шифрование для защиты безопасности данных, например, пароли шифруются и хранятся в базе данных вместо открытого текста;

  1. WebSupport

Веб-поддержка, может быть легко интегрирована в веб-среду;

  1. Caching

Кэш, например, после входа пользователя в систему, его информацию о пользователе и роли/разрешения не нужно проверять каждый раз, что может повысить эффективность;

  1. Concurrency

shiro поддерживает параллельную проверку многопоточных приложений, то есть, если один поток запускает другой поток, разрешения могут распространяться автоматически;

  1. Testing

обеспечить поддержку тестирования;

  1. Run As

разрешить одному пользователю выдавать себя за другого пользователя (если они позволяют это) для получения доступа;

  1. Remember Me

Запомните меня, это очень распространенная функция, то есть авторизовавшись один раз, вам не нужно авторизоваться при следующем заходе.

    Примечание: Shiro не будет поддерживать пользователей и разрешения; они должны быть разработаны/предоставлены нами, а затем введены в Shiro через соответствующий интерфейс. Что касается дизайна, об интеграции ssm в shiro поговорим позже.

2.4, Описание архитектуры

image-20200927210420029

  1. Subject

Субъект — это субъект, внешнее приложение взаимодействует с субъектом, субъект записывает текущего работающего пользователя и понимает понятие пользователя как субъекта текущей операции, которым может быть пользователь, запрошенный через браузер или запущенную программу. Субъект — это интерфейс в shiro. Интерфейс определяет множество методов, связанных с аутентификацией и авторизацией. Внешние программы аутентифицируются и авторизуются субъектом, а субъект аутентифицируется и авторизуется SecurityManager.

  1. SecurityManager

SecurityManager — менеджер безопасности, который управляет безопасностью всех субъектов, является ядром shiro и отвечает за управление безопасностью всех субъектов. Аутентификация и авторизация субъекта могут быть выполнены через SecurityManager.По сути, SecurityManager аутентифицируется через Authenticator, авторизуется через Authorizer, а сеанс управляется через SessionManager.

SecurityManager - это интерфейс, унаследованный аутентификатор, авторизатор, SessionManager три интерфейса.

  1. Authenticator

Аутентификатор Authenticator, то есть аутентификация удостоверения пользователя, Authenticator представляет собой интерфейс, предоставляющий класс реализации ModularRealmAuthenticator, который ModularRealmAuthenticator в основном отвечает большинству потребностей, но также может настраивать аутентификатор.

  1. Authorizer

Авторизатор — это авторизатор.Пользователь проходит аутентификацию через аутентификатор.При доступе к функции авторизатору необходимо определить, есть ли у пользователя разрешение на работу с этой функцией.

  1. Realm

Область — это область, которая эквивалентна источнику данных источника данных. SecurityManager необходимо получить данные разрешений пользователя через область для проверки подлинности безопасности. база данных.

**Примечание: не интерпретируйте область как просто получение данных из источника данных.В области также есть соответствующие коды для аутентификации и проверки авторизации. **

  1. sessionManager

sessionManager - это управление сеансом. Платформа Shiro определяет набор управления сеансом. Он не зависит от сеанса веб-контейнера, поэтому shiro можно использовать в не-веб-приложениях или он может централизованно управлять сеансами распределенных приложений. Эта функция позволяет реализовать единый вход.

  1. SessionDAO

SessionDAO — это дао сеанса, представляющее собой набор интерфейсов для операций сеанса сеанса.Например, если вы хотите сохранить сеанс в базе данных, вы можете сохранить сеанс в базе данных через jdbc.

  1. CacheManager

CacheManager — это управление кешем, которое сохраняет в кеше данные о разрешениях пользователя, что может повысить производительность.

  1. Cryptography

Криптография — это управление паролями, а shiro предоставляет набор компонентов шифрования/дешифрования для упрощения разработки. Например, он предоставляет часто используемые функции, такие как хеширование и шифрование/дешифрование.

2.5. Загрузите зависимости Shiro и maven

сделать ro.apache.org/download.contract...

image-20200928092649234

image-20200928092719767

  • shiro-all — это баночка со всеми функциями shiro.
  • shiro-core — это базовый пакет функций shiro.
  • shiro-web и пакеты веб-интеграции
  • пакет shiro-spring для интеграции shrio и spring

2. Начало работы с основами Широ

2.1 Описание файла Shiro.ini

  1. ini (InitializationFile) Файл инициализации с расширением системного файла Windows.

  2. При использовании Shiro вы можете подключаться к базе данных или нет.Если вы не подключаетесь к базе данных, вы можете настроить статические данные в shiro.ini

2.2 Компоненты файла Shrio.ini

[main] : определить глобальные переменные

  1. Встроенный объект securityManager.

  2. При манипулировании встроенными объектами напишите что-нибудь в [main]

[main]
securityManager.属性=值
xiaolin=123456
securityManager.对象属性=$xiaolin

[users] : определить имя пользователя и пароль

[users]
# 定义用户名为zhangsan 密码为zs
zhangsan=zs
# 定义用户名lisi密码为lisi同时具有role1和role2两个角色
lisi=lisi,role1,role2

[роли]: определить роли

[roles]
role1=权限名1,权限名2 
role2=权限3,权限4

[urls]: определите, какие встроенные URL-адреса вступают в силу.Используется в веб-приложениях.

[urls]
#url地址=内置filter或自定义filter
# 访问时出现/login的url必须去认证.支持authc对应的Filter 
/login=authc
# 任意的url都不需要进行认证等功能.
/** = anon
# 所有的内容都必须保证用户已经登录.
/**=user
# url abc 访问时必须保证用户具有role1和role2角色.
/abc=roles[“role1,role2”]

2.3, сведения о фильтре

имя фильтра Класс фильтра описывать
anon org.apache.shiro.web.filter.authc.AnonymousFilter Анонимный фильтр
authc org.apache.shiro.web.filter.authc.FormAuthenticationFilter Если вы продолжите работу, вам необходимо сделать соответствующую проверку формы, иначе она не пройдет.
authcBasic org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter Базовая фильтрация HTTP-аутентификации, если она не пройдена, перейти на домашнюю страницу входа
logout org.apache.shiro.web.filter.authc.LogoutFilter Вход и выход фильтры
noSessionCreation org.apache.shiro.web.filter.session.NoSessionCreationFilter Нет фильтра создания сеанса
perms org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter Фильтр разрешений
port org.apache.shiro.web.filter.authz.PortFilter Фильтр портов, вы можете установить, является ли это указанным портом, если нет, перейти на страницу входа
rest org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter фильтр метода http, вы можете указать, что сообщение недоступно и т. д.
roles org.apache.shiro.web.filter.authz.RolesAuthorizationFilter Фильтр ролей, чтобы определить, указывает ли текущий пользователь роль
ssl org.apache.shiro.web.filter.authz.SslFilter Запрос должен пройти через ssl, если не вернуться на страницу входа
user org.apache.shiro.web.filter.authc.UserFilter При доступе к известному пользователю, например, к функции «Запомнить меня», используйте этот фильтр.

anon: фильтр анонимной обработки, то есть вы можете получить доступ без входа в систему; обычно используется для статической фильтрации ресурсов;

Например: /static/**=анон

authc: указывает, что для использования требуется аутентификация (логин);

Например: /**=authc

роли: фильтр авторизации роли, чтобы проверить, есть ли у пользователя роль ресурса;

Например: /admin/*=roles[admin]

perms: фильтр авторизации разрешений для проверки наличия у пользователя прав доступа к ресурсам;

Например: /employee/input=perms["user:update"]

Выход: Фильтр выхода

Например: /logout=выйти

3. Сертификация

3.1 Сертификация

Процесс аутентификации - это процесс подтверждения личности пользователя. Реализованная функция - это проверка входа в систему, с которой мы знакомы. Пользователь вводит номер учетной записи и пароль и отправляет их в фоновый режим, а фон проверяет правильность пароля учетной записи, получая доступ базу данных.

3.2. Ключевые объекты сертификации

3.2.1,Тема: тема

3.2.2,Принципал: идентификационная информация

Является удостоверением субъекта (субъекта) для аутентификации, и удостоверение должно иметь唯一性, такие как имя пользователя, номер мобильного телефона, адрес электронной почты и т. д. Субъект может иметь несколько удостоверений, но должен иметь основного субъекта.

3.2.3,учетные данные: учетная информация

Это информация о безопасности, которую знает только субъект, например пароли, сертификаты и т. д.

3.3 Процесс сертификации

image-20200521204452288

image-20200707152052684

Окончательное сравнение пользователей выполняется вSimpleAccountRealmв классеdoGetAuthenticationInfoМетод завершает проверку имени пользователя.

Окончательная проверка пароля находится наAuthenticatingRealmв классеassertCredentialsMatchПроверка пароля завершена в методе, и она автоматическая, и нам не нужно делать это вручную.

3.4, реализация кода

3.4.1. Введение зависимостей

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.1.3</version>
</dependency>
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.5.2</version>
</dependency>

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.22</version>
    <scope>provided</scope>
</dependency>

3.4.2, записать ini-файл

[users]
xiaolin=666
zs=13

3.4.3, напишите тестовый класс

 /**
  * 用于测试Shiro基础
  */
  @Test
  public void testShiroBase(){
    // 创建Shiro安全管理器,是Shiro的核心
    DefaultSecurityManager securityManager = new DefaultSecurityManager();
    // 加载ini配置文件,得到配置文件中配置的用户信息
    IniRealm iniRealm = new IniRealm("classpath:shiro-authc.ini");
    // 将realm对象注入到securityManager中
    securityManager.setRealm(iniRealm);
    // 将安全管理器注入到当前环境中
    SecurityUtils.setSecurityManager(securityManager);
    // 获取subject主体对象,无论是否登录都可以获取
    Subject subject = SecurityUtils.getSubject();
    // 打印一下认证状态
    System.out.println("认证状态"+subject.isAuthenticated());
    // 创建一个携带了账号和密码的令牌
    UsernamePasswordToken token = new UsernamePasswordToken("xiaolin", "666");
    // 调用subject传入令牌进行登录
    subject.login(token);
    System.out.println("认证状态"+subject.isAuthenticated());
  }

3.4.4, Примечание

Если введенные идентификационные данные и учетные данные совпадают с теми, которые настроены в файле ini, вход в систему выполнен успешно, а статус входа — true, в противном случае — статус входа false.

Как правило, существует несколько ситуаций (создание исключений) для сбоев при входе в систему:

  1. Ошибка аккаунта:org.apache.shiro.authc.UnknownAccountException
  2. неправильный пароль:org.apache.shiro.authc.IncorrectCredentialsException

3.4.5, Анализ исходного кода аутентификации Широ

1. Вызовите метод subject.login для входа в систему, который автоматически делегирует вход в систему методу securityManager.login; 2. SecurityManager аутентифицируется Аутентификатором; 3. Класс реализации Authenticator, ModularRealmAuthenticator, вызывает realm для получения реального номера учетной записи пользователя и пароля из конфигурационного ini-файла, здесь используется IniRealm (с ним идет shiro, что эквивалентно источнику данных); 4. IniRealm сначала ищет учетную запись в ini в соответствии с учетной записью в токене.Если она не найдена, она возвращает null в ModularRealmAuthenticator.Если она найдена, она соответствует паролю.Если пароль успешно подобран, аутентификация прошедший.

image-20200707152208225

3.5 Пользовательский мир

Custom Realm часто используется в реальной разработке.Информация об учетной записи, которую нам нужно использовать, обычно поступает из программы или базы данных, а не из конфигурации файла ini, который использовался ранее.

Вызовите метод doGetAuthenticationInfo в AuthenticatingRealm, чтобы получить его. Если возвращаемая информация не равна пустой, это означает, что учетная запись существует, а затем будет выполнена проверка пароля. Если он не существует, будет выброшено UnknownAccountException напрямую.

Таким образом, если мы хотим настроить Realm, мы должны переопределить метод doGetAuthenticationInfo(), затем реализовать проверку учетной записи в этом методе и вернуть объект AuthenticationInfo вызывающей стороне верхнего уровня AuthenticatingRealm для дальнейшей проверки.

3.5.1, Царство предоставлено Широ

image-20200521212728541

3.5.2. Пространство SimpleAccountRealm

При отладке мы видим, что SimpleAccountRealm используется в сертифицированном исходном коде.

image-20200521213451998

3.5.3 Часть исходного кода SimpleAccountRealm

// 认证
public class SimpleAccountRealm extends AuthorizingRealm {
		//.......省略
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        SimpleAccount account = getUser(upToken.getUsername());

        if (account != null) {

            if (account.isLocked()) {
                throw new LockedAccountException("Account [" + account + "] is locked.");
            }
            if (account.isCredentialsExpired()) {
                String msg = "The credentials for account [" + account + "] are expired";
                throw new ExpiredCredentialsException(msg);
            }

        }

        return account;
    }

    // 授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = getUsername(principals);
        USERS_LOCK.readLock().lock();
        try {
            return this.users.get(username);
        } finally {
            USERS_LOCK.readLock().unlock();
        }
    }
}

3.6 SSM интегрирует аутентификацию Shiro

3.6.1 Добавьте зависимости

<properties>
	<shiro.version>1.5.2</shiro.version>
</properties>
<!--shiro 核心-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>${shiro.version}</version>
</dependency>
<!--shiro 的 Web 模块-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-web</artifactId>
    <version>${shiro.version}</version>
</dependency>
<!--shiro 和 Spring 集成-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>${shiro.version}</version>
</dependency>
<!--shiro 底层使用的 ehcache 缓存-->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-ehcache</artifactId>
    <version>${shiro.version}</version>
</dependency>
<!--shiro 依赖的日志包-->
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>
<!--Freemarker 的 shiro 标签库-->
<dependency>
    <groupId>net.mingsoft</groupId>
    <artifactId>shiro-freemarker-tags</artifactId>
    <version>1.0.1</version>
</dependency>

3.6.2, настроить фильтр прокси

При доступе необходимо выполнить ряд операций предварительной обработки.Широ выбирает использование фильтра filter для перехвата, потому что Широ не зависит от контейнера Spring, поэтому, когда нет springmvc, это означает, что перехватчик нельзя использовать, но фильтр другой. , пока это веб-проект можно использовать. Нам нужно настроить фильтр в web.xml.

<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>
        org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Здесь используется прокси-фильтр DelegatingFilterProxy, потому что настоящий shiroFilter должен внедрять много сложных объектов, а web.xml может настраивать только параметры строк или чисел, которые не могут быть удовлетворены, поэтому мы передаем shiroFilter в Spring для management , настроенный через XML-файл Spring. После использования прокси-фильтра DelegatingFilterProxy, но браузер отправляет запрос и перехватывается прокси-фильтром, прокси-фильтр автоматически находит его из контейнера spring.filter-nameНастройте bean-компонент с тем же именем, чтобы реализовать настоящий бизнес.

3.6.3. Создайте файл shiro.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--自定义Realm-->
  <bean id="myRealm" class="cn.linstudy.shiro.CarBusinessRealm"/>
    <!--创建安全管理器-->
  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="myRealm"/>
  </bean>
  <bean id="shiroFilter"
    class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <!--引用指定的安全管理器-->
    <property name="securityManager" ref="securityManager"/>
    <!--shiro默认的登录地址是/login.jsp 现在要指定我们自己的登录页面地址-->
    <property name="loginUrl" value="/login.html"/>
    <!--路径对应的规则-->
    <property name="filterChainDefinitions">
      <!--配置请求拦截的方式,是可以匿名还是-->
      <value>
        /empLogin=anon
        /static/**=anon
        /upload/**=anon
        /getImage=anon
        /getEmailCode=anon
        /checkEmail=anon
        /checkUsername=anon
        /error=anon
        /fronted/**=anon
        /**=authc
      </value>
    </property>
  </bean>
</beans>

3.6.4, импортировать shrio.xml

Введите shiro.xml в mvc.xml

<import resource="classpath:shiro.xml"/>

3.6.5, настроить менеджер безопасности

Нам нужно настроить менеджер безопасности в shiro.xml.

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"></bean>

3.6.6 Настройка пользовательского Realm

public class CarBusinessRealm extends AuthorizingRealm {  
@Autowired
  private EmployeeService employeeService;

  // 认证
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
      throws AuthenticationException {
    // 通过token获取用户名(用户登录的时候)
    String username = (String) token.getPrincipal();
    // 判断是否存在在数据库
    Employee employee = employeeService.selectByUsername(username);
    if (employee != null) {
      // 说明此时用户名是对的,返回一个身份对象
      return new SimpleAuthenticationInfo(employee, employee.getPassword(), this.getName());
    }
    return null;
  }
}

3.6.7. Настройка пользовательского Realm

<bean id="myRealm" class="cn.linstudy.shiro.CarBusinessRealm"/>
  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="myRealm"/>
  </bean>	

3.6.8. Изменить метод входа в систему

      try {
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        SecurityUtils.getSubject().login(token);
        Employee employee = employeeMapper.selectByUsername(username);
        return employee;
      } catch (UnknownAccountException e) {
        throw new CarBussinessException("用户名错误");
      } catch (IncorrectCredentialsException e) {
        throw new CarBussinessException("密码错误");
      }

3.7, выйти

У shiro есть встроенный метод выхода из системы, нам нужно только добавить его в правило пути в shiro.xml./logout=logoutЕго можно передать Широ для обработки.