предисловие
Основные моменты знаний, объясненные в этой статье, следующие:
- Базовые знания по управлению правами
- Модель
- Крупнозернистые и мелкозернистые концепции
- Проверьте реализацию перехвата URL
- Введение и простое знакомство с Широ
1. Базовые знания Широ
Прежде чем изучать структуру Широ, мы должны сначала понять базовые знания, которые нужны Широ:управление полномочиями
1.1 Что такое управление правами?
Пока в системе участвуют пользователи, как правило, необходимо иметь управление разрешениями., управление правами для управления доступом пользователей к системе в соответствии с правилами безопасности или политиками безопасностиПользователи управления могут получать доступ и получать доступ только к тем ресурсам, на которые они уполномочены..
Управление разрешениями делится на две категории:
- Аутентификация пользователя
- Авторизация пользователя
1.1.1 Аутентификация пользователя
Аутентификация пользователя,Когда пользователь получает доступ к системе, система должна проверить легитимность личности пользователя.
Наиболее часто используемые методы аутентификации пользователей: 1. Метод имени пользователя и пароля, 2. Аппарат для перфокарт с отпечатками пальцев, 3. Метод аутентификации на основе сертификатов. .Система проверяет, является ли личность пользователя законной, прежде чем пользователь сможет получить доступ к ресурсам системы.
Например:
- Когда мы вводим нашу учетную запись Taobao и пароль, мы можем открыть корзину покупок.
Процесс аутентификации пользователя:
- Определить, можно ли получить доступ к ресурсу без аутентификации [страница входа, домашняя страница]
- Если ресурс необходимо аутентифицировать, прежде чем к нему можно будет получить доступ, определите, аутентифицирован ли посетитель.
- Если вы еще не прошли аутентификацию, вам нужно вернуться на [Страницу входа] для аутентификации.
- Доступ к ресурсам только после аутентификации
Мы можем извлечь несколько концепций из аутентификации пользователя.
- предметное тело:Подразумевается, что пользователь, возможно программа, должен получить доступ к ресурсам системы, и система должна аутентифицировать субъекта
- основные идентификационные данные:Обычно уникальный, субъект имеет несколько личностей, но есть основной принципал [мы можем выбрать аутентификацию по удостоверению личности, аутентификацию по студенческому билету и т. д. — все это наша идентификационная информация]
- учетные данные учетные данные:Может быть пароль, сертификат, отпечаток пальца.
Суммировать:Субъект должен предоставить идентификационную информацию и учетные данные при выполнении аутентификации личности.
1.1.2 Авторизация пользователя
авторизация пользователя,Простое понимание как контроль доступа, после прохождения аутентификации пользователя,Система контролирует доступ пользователей к ресурсам, и пользователи могут получить доступ к ресурсам, только если у них есть права доступа к ресурсам..
Процесс авторизации пользователя
- Дошли до ссылки авторизации пользователя, естественно, после требуется аутентификация пользователя
- Когда пользователь обращается к ресурсу, система определяет, есть ли у пользователя разрешение на управление ресурсом.
- Если у пользователя есть разрешение, он может получить доступ, если у него нет разрешения, он не может получить доступ.
Процесс авторизации можно просто понять как:После аутентификации субъекта система осуществляет контроль доступа
Субъект должен иметь права доступа к ресурсу для доступа к ресурсу.
Разрешения/разрешения:Разрешения или разрешения для ресурсов, у субъекта есть разрешение на доступ к ресурсам, как получить доступ / работать, необходимо определить разрешение, разрешения, такие как: добавление пользователя, изменение пользователя, удаление продукта
Ресурсы можно разделить на два
- Тип ресурса:Информация о пользователе системы — это тип ресурса, который эквивалентен классу java.
- Экземпляр ресурса:Пользователь с идентификатором 001 в системе является экземпляром ресурса, который эквивалентен новому объекту Java.
1.2 Модель управления правами
В общем, мы можем извлечь следующие модели:
- Тема (аккаунт, пароль)
- Ресурс (имя ресурса, адрес доступа)
- Разрешения (имя органа, идентификатор ресурса)
- роль (имя роли)
- Отношение ролей и разрешений (идентификатор роли, идентификатор разрешения)
- Связь субъекта и роли (идентификатор субъекта, идентификатор роли)
Обычно таблицы ресурсов и разрешений объединяются в одну таблицу разрешений в корпоративной разработке следующим образом:
- Ресурс (имя ресурса, адрес доступа)
- Разрешения (имя органа, идентификатор ресурса)
В сочетании как:
- Разрешения (имя органа, имя ресурса, адрес доступа к ресурсу)
1.3 Назначение разрешений
Пользователям должны быть назначены соответствующие разрешения для доступа к соответствующим ресурсам. Разрешения — это разрешения на работу с ресурсами.
обычно даютЧтобы назначать разрешения на ресурсы пользователям, информация о разрешениях должна сохраняться, например храниться в реляционной базе данных.. Запись информации о пользователях, управлении полномочиями и информации о полномочиях, назначенной пользователями, в базу данных (модель данных полномочий)
1.3.1 Управление доступом на основе ролей
RBAC (управление доступом на основе ролей), управление доступом на основе ролей.
//如果该user是部门经理则可以访问if中的代码
if(user.hasRole('部门经理')){
//系统资源内容
//用户报表查看
}
Роли разделены для людей,Люди как пользователи относятся к активному контенту в системе.Если ресурсы, к которым может получить доступ роль, изменяются, вам необходимо изменить свой код.,
if(user.hasRole('部门经理') || user.hasRole('总经理') ){
//系统资源内容
//用户报表查看
}
Управление доступом на основе ролей не способствует обслуживанию системы (масштабируемость невелика).
1.3.2 Управление доступом на основе ресурсов
RBAC (управление доступом на основе ресурсов), управление доступом на основе ресурсов.
Ресурсы в системе постоянны, например, ресурсами являются:Метод в классе, кнопка на странице.
对资源的访问需要具有permission权限,代码可以写为:
if(user.hasPermission ('用户报表查看(权限标识符)')){
//系统资源内容
//用户报表查看
}
Для управления правами рекомендуется использовать управление доступом на основе ресурсов..
2. Общие и подробные разрешения
Детальное управление разрешениями: управление разрешениями для экземпляров ресурсов. Экземпляр ресурса — это специфика типа ресурса, например: соединение модификации с идентификатором пользователя 001, информация о пользователе класса 1110 и сотрудники административного отдела.Детальное управление разрешениями — это управление разрешениями на уровне данных.
Грубое управление правами Например, суперадминистраторы могут получить доступ ко всем страницам, таким как страницы добавления пользователей и информация о пользователе. Администраторы отдела могут получить доступ к странице информации о пользователе, включая все кнопки на странице.
Крупнозернистые и мелкозернистые примеры:
系统有一个用户列表查询页面,对用户列表查询分权限,
如果粗颗粒管理,张三和李四都有用户列表查询的权限,张三和李四都可以访问用户列表查询。
进一步进行细颗粒管理,张三(行政部)和李四(开发部)只可以查询自己本部门的用户信息。
张三只能查看行政部 的用户信息,李四只能查看开发部门的用户信息。
细粒度权限管理就是数据级别的权限管理。
2.1 Как реализовать крупномасштабное управление правами?
Грубое управление разрешениями стало прощеИзвлеките код управления полномочиями и обработайте его единообразно на уровне системной архитектуры.. Например: поПерехватчик Springmvc реализует авторизацию.
детальное управление разрешениямиНет общности на уровне данных, для детального управления разрешениямичасть бизнес-логики системы,Это относительно просто обрабатывать на бизнес-уровне.
Например:Менеджер отдела запрашивает только информацию о сотруднике отдела и предоставляет параметр идентификатора отдела в интерфейсе службы. Контроллер получает, к какому отделу принадлежит пользователь в соответствии с текущей информацией о пользователе. При вызове службы идентификатор отдела передается в службы, так что пользователь может запрашивать только этот отдел.
2.1.1 Перехват на основе URL
Метод, основанный на перехвате URL-адресов, является широко используемым методом в реальной разработке.
Для веб-системы перехват URL-адресов может быть реализован через фильтр-фильтр, а перехват на основе URL-адресов также может быть реализован перехватчиком springmvc.
2.2.2 Реализовано с использованием структуры управления правами
Для крупномасштабного управления правами рекомендуется использовать превосходную структуру управления правами, чтобы сохранить успех разработки и повысить эффективность разработки.
Shiro — превосходная система управления правами.
3. Проверьте блокировку URL-адресов
Мы также использовали несколько URL-адресов для перехвата разрешений на пути к обучению.
В то время мы добавляли и удаляли систему управления для проверки разрешений.Но ресурс не добавляется в таблицу разрешений, вместо этого мы используем коллекцию Map.blog.CSDN.net/hon_3 has/Aretti…
Позже мы узнали о динамических прокси и аннотациях, а также сделали перехват на основе аннотаций.
- Когда контроллер получает объект службы, фабрика служб возвращает динамический прокси-объект.
- Контроллер использует прокси-объект для вызова метода, и прокси-объект будет анализировать, есть ли аннотация в методе.
- Если есть аннотация, то нам нужно судить, аутентифицирован ли субъект, и если да, то судить, имеет ли субъект полномочия
- Когда мы разберем, что авторитет темы соответствует авторитету нашей аннотации, мы его опубликуем!
blog.CSDN.net/hon_3 has/Aretti…
Процесс:
3.1 Аутентифицированные компоненты JavaBean
Раньше мы помещали аутентификацию в объект Javabean по умолчанию. Теперь, когда мы готовы изучать Широ, мы должны быть профессионалами и получить его.JavaBean, предназначенный для хранения информации аутентификации
/**
* 用户身份信息,存入session 由于tomcat将session会序列化在本地硬盘上,所以使用Serializable接口
*
* @author Thinkpad
*
*/
public class ActiveUser implements java.io.Serializable {
private String userid;//用户id(主键)
private String usercode;// 用户账号
private String username;// 用户名称
private List<SysPermission> menus;// 菜单
private List<SysPermission> permissions;// 权限
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsercode() {
return usercode;
}
public void setUsercode(String usercode) {
this.usercode = usercode;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public List<SysPermission> getMenus() {
return menus;
}
public void setMenus(List<SysPermission> menus) {
this.menus = menus;
}
public List<SysPermission> getPermissions() {
return permissions;
}
public void setPermissions(List<SysPermission> permissions) {
this.permissions = permissions;
}
}
сертифицированный сервис
@Override
public ActiveUser authenticat(String userCode, String password)
throws Exception {
/**
认证过程:
根据用户身份(账号)查询数据库,如果查询不到用户不存在
对输入的密码 和数据库密码 进行比对,如果一致,认证通过
*/
//根据用户账号查询数据库
SysUser sysUser = this.findSysUserByUserCode(userCode);
if(sysUser == null){
//抛出异常
throw new CustomException("用户账号不存在");
}
//数据库密码 (md5密码 )
String password_db = sysUser.getPassword();
//对输入的密码 和数据库密码 进行比对,如果一致,认证通过
//对页面输入的密码 进行md5加密
String password_input_md5 = new MD5().getMD5ofStr(password);
if(!password_input_md5.equalsIgnoreCase(password_db)){
//抛出异常
throw new CustomException("用户名或密码 错误");
}
//得到用户id
String userid = sysUser.getId();
//根据用户id查询菜单
List<SysPermission> menus =this.findMenuListByUserId(userid);
//根据用户id查询权限url
List<SysPermission> permissions = this.findPermissionListByUserId(userid);
//认证通过,返回用户身份信息
ActiveUser activeUser = new ActiveUser();
activeUser.setUserid(sysUser.getId());
activeUser.setUsercode(userCode);
activeUser.setUsername(sysUser.getUsername());//用户名称
//放入权限范围的菜单和url
activeUser.setMenus(menus);
activeUser.setPermissions(permissions);
return activeUser;
}
Контроллер обрабатывает аутентификацию,Если аутентификация прошла успешно, сохраните информацию об аутентификации в Session
@RequestMapping("/login")
public String login(HttpSession session, String randomcode,String usercode,String password)throws Exception{
//校验验证码,防止恶性攻击
//从session获取正确验证码
String validateCode = (String) session.getAttribute("validateCode");
//输入的验证和session中的验证进行对比
if(!randomcode.equals(validateCode)){
//抛出异常
throw new CustomException("验证码输入错误");
}
//调用service校验用户账号和密码的正确性
ActiveUser activeUser = sysService.authenticat(usercode, password);
//如果service校验通过,将用户身份记录到session
session.setAttribute("activeUser", activeUser);
//重定向到商品查询页面
return "redirect:/first.action";
}
Перехватчик аутентификации
//在执行handler之前来执行的
//用于用户认证校验、用户权限校验
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
//得到请求的url
String url = request.getRequestURI();
//判断是否是公开 地址
//实际开发中需要公开 地址配置在配置文件中
//从配置中取逆名访问url
List<String> open_urls = ResourcesUtil.gekeyList("anonymousURL");
//遍历公开 地址,如果是公开 地址则放行
for(String open_url:open_urls){
if(url.indexOf(open_url)>=0){
//如果是公开 地址则放行
return true;
}
}
//判断用户身份在session中是否存在
HttpSession session = request.getSession();
ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
//如果用户身份在session中存在放行
if(activeUser!=null){
return true;
}
//执行到这里拦截,跳转到登陆页面,用户进行身份认证
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
//如果返回false表示拦截不继续执行handler,如果返回true表示放行
return false;
}
Перехватчик авторизации
//在执行handler之前来执行的
//用于用户认证校验、用户权限校验
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
//得到请求的url
String url = request.getRequestURI();
//判断是否是公开 地址
//实际开发中需要公开 地址配置在配置文件中
//从配置中取逆名访问url
List<String> open_urls = ResourcesUtil.gekeyList("anonymousURL");
//遍历公开 地址,如果是公开 地址则放行
for(String open_url:open_urls){
if(url.indexOf(open_url)>=0){
//如果是公开 地址则放行
return true;
}
}
//从配置文件中获取公共访问地址
List<String> common_urls = ResourcesUtil.gekeyList("commonURL");
//遍历公用 地址,如果是公用 地址则放行
for(String common_url:common_urls){
if(url.indexOf(common_url)>=0){
//如果是公开 地址则放行
return true;
}
}
//获取session
HttpSession session = request.getSession();
ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
//从session中取权限范围的url
List<SysPermission> permissions = activeUser.getPermissions();
for(SysPermission sysPermission:permissions){
//权限的url
String permission_url = sysPermission.getUrl();
if(url.indexOf(permission_url)>=0){
//如果是权限的url 地址则放行
return true;
}
}
//执行到这里拦截,跳转到无权访问的提示页面
request.getRequestDispatcher("/WEB-INF/jsp/refuse.jsp").forward(request, response);
//如果返回false表示拦截不继续执行handler,如果返回true表示放行
return false;
}
Конфигурация перехватчика:
<!--拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 用户认证拦截 -->
<mvc:mapping path="/**" />
<bean class="cn.itcast.ssm.controller.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<!-- 授权拦截 -->
<mvc:mapping path="/**" />
<bean class="cn.itcast.ssm.controller.interceptor.PermissionInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
4. Что такое Широ
shiro — это фреймворк с открытым исходным кодом apache,Это структура управления правами, которая реализует аутентификацию и авторизацию пользователей..
В Spring есть Spring Security (ранее Acegi), который является фреймворком разрешений, он слишком сильно зависит от Spring и не так прост в использовании, как shiro. shiro не зависит от spring, shiro может не только реализовать управление полномочиями веб-приложений, но и систему c/s, управление полномочиями распределенной системы,Shiro — это облегченный фреймворк, и все больше и больше корпоративных проектов начинают использовать shiro.
Широ Архитектура:
- Субъект: Субъект, который может быть пользователем или программой.Для доступа к системе система должна аутентифицировать и авторизовать субъекта.
- securityManager: Менеджер безопасности, аутентификация и авторизация принципала выполняются через securityManager.
- аутентификатор: аутентификатор, аутентификация субъекта окончательно осуществляется через аутентификатор.
- авторизатор: авторизатор, принципал, наконец, авторизован авторизатором.
- sessionManager: в веб-приложениях веб-контейнеры обычно используются для управления сеансами, а shiro также предоставляет набор методов управления сеансами.
- SessionDao: управляйте данными сеанса через SessionDao и используйте sessionDao для персонализированного хранения данных сеанса.
- Cache Manager: Cache Manager, который в основном кэширует данные сеанса и авторизации.Например, данные авторизации кэшируются через cacheManager, и он интегрирован с ehcache для управления кэшированными данными.
- область: домен, область, эквивалентная источнику данных,Доступ к данным, связанным с аутентификацией и авторизацией, через область.
криптография: управление паролями, предоставляет набор компонентов шифрования/дешифрования для легкой разработки. Например, он предоставляет часто используемые функции, такие как хеширование и шифрование/дешифрование.
- Например, алгоритм хеширования md5.
5. Зачем использовать Широ
Когда мы используем перехват URL,Настройка всех URL-адресов громоздка и сложна в обслуживании.
И наша реализация ШироСистема управления правами, эффективно повышающая эффективность разработки, тем самым снижая затраты на разработку.
6. Сертификация Широ
6.1 Импорт пакета jar
Используем координаты Maven на линии
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-quartz</artifactId>
<version>1.2.3</version>
</dependency>
Конечно, мы также можем импортировать в него все jar-пакеты, связанные с Shiro.
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.2.3</version>
</dependency>
6.2Процесс сертификации Широ
6.2.1 Создание фабрики через конфигурационный файл
// 用户登陆和退出
@Test
public void testLoginAndLogout() {
// 创建securityManager工厂,通过ini配置文件创建securityManager工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory(
"classpath:shiro-first.ini");
// 创建SecurityManager
SecurityManager securityManager = factory.getInstance();
// 将securityManager设置当前的运行环境中
SecurityUtils.setSecurityManager(securityManager);
// 从SecurityUtils里边创建一个subject
Subject subject = SecurityUtils.getSubject();
// 在认证提交前准备token(令牌)
// 这里的账号和密码 将来是由用户输入进去
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
"111111");
try {
// 执行认证提交
subject.login(token);
} catch (AuthenticationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 是否认证通过
boolean isAuthenticated = subject.isAuthenticated();
System.out.println("是否认证通过:" + isAuthenticated);
// 退出操作
subject.logout();
// 是否认证通过
isAuthenticated = subject.isAuthenticated();
System.out.println("是否认证通过:" + isAuthenticated);
}
6.3 Резюме
Роль ModularRealmAuthenticator для аутентификации,Необходимо вызвать область для запроса информации о пользователе (информация о пользователе существует в базе данных)ModularRealmAuthenticator выполняет сравнение паролей (процесс аутентификации). область: вам необходимо запросить базу данных в соответствии с идентификационной информацией в токене (файл конфигурации ini используется для программы входа),Если найдено, что пользователь возвращает информацию для аутентификации, если запрос завершается неудачно, возвращает значение null..
6.4 Пользовательский мир
Как видно из первого процесса сертификации, который мы называем процессом,Это аутентификатор, который отправляется в область для запроса наших соответствующих данных.. Область по умолчанию напрямую сравнивается с файлом конфигурации.В нашей разработке мы позволяем realm отправляться в базу данных для сравнения.Поэтому нам нужно настроить область
public class CustomRealm extends AuthorizingRealm {
// 设置realm的名称
@Override
public void setName(String name) {
super.setName("customRealm");
}
// 用于认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
// token是用户输入的
// 第一步从token中取出身份信息
String userCode = (String) token.getPrincipal();
// 第二步:根据用户输入的userCode从数据库查询
// ....
// 如果查询不到返回null
//数据库中用户账号是zhangsansan
/*if(!userCode.equals("zhangsansan")){//
return null;
}*/
// 模拟从数据库查询到密码
String password = "111112";
// 如果查询到返回认证信息AuthenticationInfo
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
userCode, password, this.getName());
return simpleAuthenticationInfo;
}
// 用于授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
// TODO Auto-generated method stub
return null;
}
}
6.5 Настройка области
Необходимо настроить область в shiro-realm.ini для внедрения в securityManager.
6.6 Проверка пользовательской области
Как и в стартовой программе выше, вам нужно изменить путь к файлу конфигурации ini:
同上边的入门程序,需要更改ini配置文件路径:
Factory<SecurityManager> factory = new IniSecurityManagerFactory(
"classpath:shiro-realm.ini");
6.7 Алгоритмы хеширования
Если мы знаем md5, мы будем знать, что md5 необратим, но если установлены какие-то пароли с относительно низкой безопасностью: 111111... Это необратимо, но открытый текст, соответствующий md5, все еще может быть получен алгоритмом грубой силы...
Рекомендуется добавлять соль (salt) при хешировании md5.Шифрование эквивалентно хешированию исходного пароля + соль.\
Метод хеширования при обычном использовании:
- Исходный пароль + соль хешируется в программе, значение хэша хранится в базе, соль тоже хранится в базе.
контрольная работа:
public class MD5Test {
public static void main(String[] args) {
//原始 密码
String source = "111111";
//盐
String salt = "qwerty";
//散列次数
int hashIterations = 2;
//上边散列1次:f3694f162729b7d0254c6e40260bf15c
//上边散列2次:36f2dfa24d0a9fa97276abbe13e596fc
//构造方法中:
//第一个参数:明文,原始密码
//第二个参数:盐,通过使用随机数
//第三个参数:散列的次数,比如散列两次,相当 于md5(md5(''))
Md5Hash md5Hash = new Md5Hash(source, salt, hashIterations);
String password_md5 = md5Hash.toString();
System.out.println(password_md5);
//第一个参数:散列算法
SimpleHash simpleHash = new SimpleHash("md5", source, salt, hashIterations);
System.out.println(simpleHash.toString());
}
}
6.8 Пользовательская область поддерживает md5
пользовательское царство
public class CustomRealmMd5 extends AuthorizingRealm {
// 设置realm的名称
@Override
public void setName(String name) {
super.setName("customRealmMd5");
}
// 用于认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
// token是用户输入的
// 第一步从token中取出身份信息
String userCode = (String) token.getPrincipal();
// 第二步:根据用户输入的userCode从数据库查询
// ....
// 如果查询不到返回null
// 数据库中用户账号是zhangsansan
/*
* if(!userCode.equals("zhangsansan")){// return null; }
*/
// 模拟从数据库查询到密码,散列值
String password = "f3694f162729b7d0254c6e40260bf15c";
// 从数据库获取salt
String salt = "qwerty";
//上边散列值和盐对应的明文:111111
// 如果查询到返回认证信息AuthenticationInfo
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
userCode, password, ByteSource.Util.bytes(salt), this.getName());
return simpleAuthenticationInfo;
}
// 用于授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
// TODO Auto-generated method stub
return null;
}
}
Конфигурационный файл:
контрольная работа:
// 自定义realm实现散列值匹配
@Test
public void testCustomRealmMd5() {
// 创建securityManager工厂,通过ini配置文件创建securityManager工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory(
"classpath:shiro-realm-md5.ini");
// 创建SecurityManager
SecurityManager securityManager = factory.getInstance();
// 将securityManager设置当前的运行环境中
SecurityUtils.setSecurityManager(securityManager);
// 从SecurityUtils里边创建一个subject
Subject subject = SecurityUtils.getSubject();
// 在认证提交前准备token(令牌)
// 这里的账号和密码 将来是由用户输入进去
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",
"222222");
try {
// 执行认证提交
subject.login(token);
} catch (AuthenticationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 是否认证通过
boolean isAuthenticated = subject.isAuthenticated();
System.out.println("是否认证通过:" + isAuthenticated);
}
7. Резюме
- Аутентификация пользователя и авторизация пользователя являются основой Shiro.Аутентификация пользователя на самом деле является операцией входа в систему, а авторизация пользователя на самом деле является операцией перехвата ресурсов.
- В модели управления разрешениями мы обычно управляем ресурсами в таблице разрешений.
- Мы можем перехватывать на основе ролей или на основе ресурсов. Если он основан на перехвате ролей, то при изменении разрешений роли код нужно модифицировать**. Рекомендуется перехват на основе ресурсов**
- В этом перехвате URL мы используем JavaBean для инкапсуляции всей аутентификационной информации. Когда пользователь входит в систему, мы инкапсулируем доступ пользователя к строке меню и доступ к ресурсам в JavaBean.
- При использовании перехватчика для аутентификации пользователя нам нужно только определить, есть ли объект JavaBen в домене Session.
- Когда перехватчик выполняет авторизацию пользователя, нам нужно определить, могут ли разрешения в JavaBean получить доступ к ресурсу.
- Предыдущий метод перехвата URL-адресов требовал, чтобы все URL-адреса управлялись в базе данных. Очень хлопотный и сложный в обслуживании.
- Мы надеемся, что когда Широ пойдет на аутентификацию, он будет использовать область для запроса данных в базе данных. И наше настоящее значение по умолчанию — запрашивать данные файла конфигурации.
- Поэтому нам нужно настроить reaml так, чтобы он обращался к базе данных для запроса данных. Просто наследуйте класс AuthorizingRealm.
- Конечно, кастомизированный реал также должен прописать местоположение нашего кастомного реалла в файле конфигурации.
- Алгоритмы хеширования предназначены для предотвращения взлома паролей другими лицами.Мы можем солить и хэшировать исходный пароль, что затрудняет его взлом.
- Пользовательский reaml также поддерживает алгоритм хеширования, такой же, нам еще нужно настроить его в конфигурационном файле.
Если в статье есть какие-либо ошибки, пожалуйста, поправьте меня, и мы сможем общаться друг с другом. Учащиеся, привыкшие читать технические статьи в WeChat и желающие получить больше ресурсов по Java, могутОбратите внимание на публичный аккаунт WeChat: Java3y