QW-Admin-Server
1. Структура проекта
2. Контроль доступа
2.1. Введение
В этой системе реализован только контроль функциональных разрешений на основе модели RBAC с детализацией до уровня интерфейса. Первоначально система не использовала фреймворк для контроля доступа, но позже интегрировала Shiro. Чтобы обеспечить совместимость с существующей системой контроля доступа, были внесены следующие изменения в конфигурацию Shiro:
— Реализован класс QWPermissionProxy для проверки функциональных разрешений, и окончательная проверка делегирована AuthServiceImpl. — Написаны собственные реализации логики входа и автоматического входа. — Создан класс QWAuthenticationStrategyImpl для поддержки нескольких реализаций Realm для аутентификации и проверки разрешений. — Функциональные разрешения названы с использованием символа «-» (в отличие от стиля Shiro, где используется символ «:»).
В настоящее время система Realm не поддерживает стиль разрешений Shiro, использование не вызовет исключений, но результаты всегда будут ложными.
2.2. Поддержка аннотаций разрешений Shiro
Аннотации разрешений действуют на методах @Controller. Реализация логики находится в методе com.qiwen.base.config.interceptor.QWAbstractAuthInterceptor.hasShiroAuthcAnnotation().
Аннотации | Описание |
---|---|
@RequiresPermissions | Указывает набор разрешений, необходимых для доступа к интерфейсу. |
@RequiresRoles | Указывает набор ролей, необходимых для доступа к интерфейсу. |
@RequiresAuthentication | Указывает, что доступ к интерфейсу требует аутентифицированного пользователя, прошедшего аутентификацию не автоматически. |
@RequiresUser | Указывает, что для доступа к интерфейсу требуется аутентифицированный пользователь. |
@RequiresGuest | Указывает, что интерфейс недоступен для аутентифицированных пользователей. Например, доступ к интерфейсам входа. |
@Desc (настраиваемая) | Указывает набор разрешений, конфигурацию журнала и метаданные функциональных разрешений. |
2.3. Примеры использования аннотаций разрешений
2.3.1. Исходные аннотации Shiro
@RestController
@RequestMapping("/foo")
public static class FooController {
// Требуется разрешения foo1 & foo2
@RequiresPermissions("foo1 & foo2")
public String testRequiresPermissionOfLogicAnd() {
// do something...
}
// Требуется разрешение foo1 | foo2
@RequiresPermissions("foo1 | foo2")
public String testRequiresPermissionOfLogicOr() {
// do something...
}
// Требуется роли foo1 и foo2, логика 'или' не описана
@RequiresRoles({"foo1", "foo2"})
@RequiresPermissions("foo1 | foo2")
public String testRequiresPermission() {
// do something...
}
// @RequiresAuthentication, @RequiresUser, @RequiresGuest используются проще, без описания
}
2.3.2. Расширенная аннотация @Desc
/**
* Родительское меню имеет имя user-admin и предоставляет функцию группировки разрешений.
*/
@Desc(groupName="user-admin")
@RestController
@RequestMapping("/foo")
public static class FooController {
/**
* Требуется разрешение user-add, описание разрешения: добавление пользователя, эта информация будет автоматически добавлена в базу данных.
* Обратите внимание: когда мы знаем, что нам нужно добавить новое разрешение в систему самостоятельно, мы можем использовать эту аннотацию.
* В других местах мы можем использовать это функциональное разрешение через @RequiresPermissions("user-add").
*/
@Desc(name="user-add", value="添加用户")
public String addUser() {
// do something...
}
}
С этой конфигурацией будет создана следующая структура атрибутов разрешений:
user-admin
|---user-add
|---...
Многоуровневая структура разрешений:
/**
* Родительское меню имеет имя user-admin и предоставляет функцию группировки разрешений.
*/
@Desc(name="base-system > user-admin")
@RestController
@RequestMapping("/foo")
public static class FooController {
/**
* Требуется разрешение user-add, описание разрешения: добавление пользователя, эта информация будет автоматически добавлена в базу данных.
* Обратите внимание: когда мы знаем, что нам нужно добавить новое разрешение в систему самостоятельно, мы можем использовать эту аннотацию.
* В других местах мы можем использовать это функциональное разрешение через @RequiresPermissions("user-add").
*/
@Desc(name="user-add", value="添加用户") **jobGroupName = jobDetail.getKey().getGroup();**
**workLog.setGroupName(jobGroupName);**
**workLog.setName(jobName);**
**workLog.setJobClass(jobDetail.getJobClass().getName());**
**workLog.setStatus(1);**
**workLogService.save(workLog);**
}
## 2、自定义任务扫描配置
```yaml
qw.constant.web:
# 配置 com.qiwen.base.config.job、com.qiwen.yjyx.config.job 包下的 Job 子类都会
# 被添加到可选新增任务列表中
quartz-job-scan-packages:
- com.qiwen.base.config.job
- com.qiwen.yjyx.config.job
После выполнения указанных действий в разделе «Управление задачами» > «Добавить задачу» автоматически появится опция «Тестовая задача».
Каждый Job может существовать только в одном экземпляре.
Обычно в проектах с разделением переднего и заднего плана статические ресурсы размещаются на отдельном сервере статических ресурсов, чтобы обеспечить доступ к ним. Java-приложения не предназначены для обработки статических ресурсов. Система предоставляет простой способ интеграции и настройки быстрого доступа к внешним статическим ресурсам. Конфигурация выглядит следующим образом:
qw.constant.web:
# Настройка двух путей к внешним статическим ресурсам
external-web-resources:
# Статические ресурсы в ${qw-global-base-dir}www/ можно получить через /yjyxapp/**
- resource-handlers:
- /yjyxapp/**
resource-locations:
- file:${qw-global-base-dir}www/
# Имя компонента управления кэшем
cache-control-bean-name: yjyxDefaultCacheControlBean
# Принцип тот же...
- resource-handlers:
- /web-admin/**
resource-locations:
- file:D:/data/YGWL_COMPANY/qw-admin/qw-admin-web/static/
cache-control-bean-name: yjyxDefaultCacheControlBean
yjyxDefaultCacheControlBean
конфигурация:
package com.qiwen.yjyx.config;
import com.qiwen.base.config.db.QWPrivilegeTreeSorter;
import com.qiwen.base.entity.Privilege;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Slf4j
@Configuration
public class YJYXBeanConfig {
@Bean(name = "yjyxDefaultCacheControlBean")
public CacheControl yjyxDefaultCacheControlBean() {
// Кэширование на 365 дней, см. документацию SpringMVC для использования.
return CacheControl.maxAge(365, TimeUnit.DAYS);
}
}
/**
*
* @author yangxiuchu
*/
@Slf4j
@Component
public class FooPInterceptor extends QWAbstractInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// do something
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// do something
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// do something
}
/**
* Настройка пути перехвата
*/
@Override
public String[] getPathPatterns() {
String[] patterns = { "/yjyx/admin/v1/**" };
return patterns;
}
/**
* Настройка порядка перехватчика, по умолчанию 0
*/
@Override
public int getOrder() {
return super.getOrder();
}
}
Все подклассы com.qiwen.base.config.interceptor.QWAbstractInterceptor
в системе будут автоматически зарегистрированы как перехватчики Spring MVC.
Система предоставляет простую функцию хранения файлов на основе локальной файловой системы. См. com.qiwen.base.controller.admin.AdminImgRestController
.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )