Light Security — это простой и мощный фреймворк управления правами доступа, основанный на jwt
, который можно использовать вместе с Spring Boot
. Он поддерживает Spring MVC
и WebFlux
.
RESTful
управления правами доступаSpring Security
Shiro
, но не реализует сложную стратегию аутентификации (реализация также проста, см. расширяемость
)СОВЕТ
Для быстрого старта см. директорию
light-security-example
проекта, в ней приведены подробные шаги тестирования.
Настройка конфигурации: ```yaml сервер: порт: 8009 легкий-безопасность: # Конфигурация правил доступа: указывает, что запросы методом {http-method} к пути {path} должны удовлетворять условию {expression} спецификации: - http-метод: ANY путь: /login выражение: "anon()" - http-метод: ANY путь: /пользователь выражение: "hasAnyRoles('пользователь','администратор')" - http-метод: ANY путь: /пользователь-без-доступа выражение: "hasAllRoles('пользователь','администратор','xx')" - http-метод: GET путь: /ошибка выражение: "anon()" - http-метод: ANY путь: /** выражение: "hasLogin()" jwt: # Алгоритм подписи JWT алгоритм: hs512 # Секрет JWT секрет: {secret} # Время жизни JWT в секундах время-жизни-в-секундах: 1209600
* Код:
```java
@RequestMapping
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class TestController {
private final UserOperator userOperator;
private final JwtOperator operator;
/**
* Демонстрация получения информации о текущем авторизованном пользователе
* - Этот маршрут требует наличия роли 'пользователь' или 'администратор', см. application.yml
*
* @return Информация о пользователе
*/
@GetMapping("/пользователь")
public User пользователь() {
return userOperator.getПользователь();
}
@GetMapping("/пользователь-без-доступа")
public User пользовательБезДоступа() {
return userOperator.getПользователь();
}
## Демонстрация управления доступом с помощью аннотаций
### Метод аннотацияТест()
```java
/**
* Демонстрация управления доступом с помощью аннотаций
*
* @return Если есть права доступа, вернуть "Вы имеете роли 'пользователь' и 'администратор'"
*/
@GetMapping("/annotation-test")
@PreAuthorize("hasAllRoles('пользователь','администратор')")
public String annotationTest() {
return "Вы имеете роли 'пользователь' и 'администратор'";
}
@GetMapping("/annotation-test-without-access")
@PreAuthorize("hasAllRoles('пользователь','администратор','xx')")
public String annotationTestWithoutAccess() {
return "Вы имеете роли 'пользователь', 'администратор' и 'xx'";
}
@GetMapping("/login")
public String loginReturnToken() {
User user = User.builder()
.id(1)
.username("Иван")
.roles(Arrays.asList("пользователь", "администратор"))
.build();
return operator.generateToken(user);
}
## Конфигурация прав доступа на основе кода
```java
@Configuration
public class LightSecurityConfiguration {
@Bean
public SpecRegistry specRegistry() {
return new SpecRegistry()
.add(HttpMethod.GET, "/user", "hasAnyRoles('user')")
.add(HttpMethod.ANY, "/**", "hasLogin()");
}
}
В этом случае конфигурацию в application.yml
, представленную ниже, можно удалить, так как конфигурация на основе кода имеет более высокий приоритет, а конфигурация из файла будет недействительной.
light-security:
# Конфигурация прав доступа: указывает, что запросы методом {http-method} к пути {path} должны удовлетворять условию {expression}.
spec-list:
- http-method: ANY
path: /login
expression: "anon()"
- http-method: ANY
path: /user
expression: "hasAnyRoles('user', 'admin')"
- http-method: ANY
path: /user-no-access
expression: "hasAllRoles('user', 'admin', 'xx')"
- http-method: GET
path: /error
expression: "anon()"
- http-method: ANY
path: /**
expression: "hasLogin()"
```
В данном случае все необходимые строки уже были переведены, поэтому изменения минимальны.#### Расширяемые точки
| Класс | Описание |
| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| com.itmuch.lightsecurity.jwt.UserOperator | Предоставляет операции с пользователями, такие как получение информации о пользователе из токена. |
| com.itmuch.lightsecurity.el.PreAuthorizeExpressionRoot | Предоставляет поддержку выражений, таких как `hasAnyRoles('user')`. Для новых возможностей достаточно добавить новые методы. |
| com.itmuch.lightsecurity.annotation.support.PreAuthorizeAspect | Поддерживает аннотацию `@PreAuthorize("hasAllRoles('user', 'admin')")`. |
### Программная модель WebFlux
> **СОВЕТЫ**
>
> Быстрый старт подробно описан в директории проекта `light-security-webflux-example`, где также приведены шаги тестирования.
#### Конфигурация прав доступа на основе файла конфигурации
* Добавление зависимостей
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.itmuch.security</groupId>
<artifactId>light-security-webflux-spring-boot-starter</artifactId>
<version>1.0.2-SNAPSHOT</version>
</dependency>
```
* Настройка конфигурации ```yaml
сервер:
порт: 8009
световая_безопасность:
# Конфигурация правил доступа: указывает, что запросы методом {http-method} к пути {path} должны удовлетворять условию {expression}
спецификации:
- http_метод: ANY
путь: /login
выражение: "anon()"
- http_метод: ANY
путь: /user
выражение: "hasAnyRoles('user', 'admin')"
- http_метод: ANY
путь: /user-no-access
выражение: "hasAllRoles('user', 'admin', 'xx')"
- http_метод: GET
путь: /error
выражение: "anon()"
- http_метод: ANY
путь: /**
выражение: "hasLogin()"
jwt:
# Алгоритм подписи jwt
алгоритм: hs512
# Секрет jwt
секрет: {secret}
# Время жизни jwt в секундах
время_жизни_в_секундах: 1209600
```* Код
```java
@RequestMapping
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class TestController {
private final ReactiveUserOperator userOperator;
private final JwtOperator operator;
/**
* Демонстрация получения информации о текущем авторизованном пользователе
* - Этот маршрут требует наличия роли user или admin для доступа, см. application.yml
*
* @return Информация о пользователе
*/
@GetMapping("/user")
public Mono<User> user() {
return userOperator.getUser();
}
@GetMapping("/user-no-access")
public Mono<User> userNoAccess() {
return userOperator.getUser();
}
/**
* Демонстрация управления доступом с помощью аннотаций
*
* @return Если есть права доступа, вернуть "У вас есть роли user и admin..."
*/
@GetMapping("/annotation-test")
@PreAuthorize("hasAllRoles('user', 'admin')")
public Mono<String> annotationTest() {
return Mono.just("У вас есть роли user и admin...");
}
@GetMapping("/annotation-test-no-access")
@PreAuthorize("hasAllRoles('user', 'admin', 'xx')")
public Mono<String> annotationTestNoAccess() {
return Mono.just("У вас есть роли user, admin и xx...");
}
/**
* Моделирование входа и выдачи токена
*
* @return Строка с токеном
*/
@GetMapping("/login")
public String loginReturnToken() {
User user = User.builder()
.id(1)
.username("张三")
.roles(Arrays.asList("user", "admin"))
.build();
return operator.generateToken(user);
}
}
```
#### Базовая конфигурация прав доступа через код
```java
@Configuration
public class LightSecurityConfiguration {
@Bean
public SpecRegistry specRegistry() {
return new SpecRegistry()
.add(HttpMethod.GET, "/user", "hasAnyRoles('user')")
.add(HttpMethod.ANY, "/**", "hasLogin()");
}
}
```На данном этапе можно удалить следующие конфигурации в `application.yml`, так как конфигурация через код имеет более высокий приоритет, а конфигурация из файла будет проигнорирована.
```yaml
light-security:
# Конфигурация прав доступа: указывает, что запросы методом {http-method} к пути {path} должны удовлетворять условию {expression}.
spec-list:
- http-method: ANY
path: /login
expression: "anon()"
- http-method: ANY
path: /user
expression: "hasAnyRoles('user', 'admin')"
- http-method: ANY
path: /user-no-access
expression: "hasAllRoles('user', 'admin', 'xx')"
- http-method: GET
path: /error
expression: "anon()"
- http-method: ANY
path: /**
expression: "hasLogin()"
```
#### Расширяемые точки
| Класс | Описание |
| -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| com.itmuch.lightsecurity.jwt.ReactiveUserOperator | Предоставляет операции с пользователями, такие как парсинг токена для получения информации о пользователе. |
| com.itmuch.lightsecurity.el.ReactivePreAuthorizeExpressionRoot | Предоставляет поддержку выражений, таких как `hasAnyRoles('user')`. Для новых возможностей достаточно создать новые методы. |
| com.itmuch.lightsecurity.annotation.support.ReactivePreAuthorizeAspect | Поддерживает аннотацию `@PreAuthorize("hasAllRoles('user', 'admin')")`. |
## Часто задаваемые вопросы
### Почему вы создали этот фреймворк?Часто люди задают мне вопросы, такие как "Как управлять безопасностью микросервисов?", "Столкнулись ли вы с проблемой Spring Security xxxx?", "Можно ли написать серию руководств по Spring Cloud Security?" и "Столкнулись ли вы с проблемой Shiro xxxx?"?
Это стало очень надоедливым, поэтому я начал активно отвечать; затем стал отвечать пассивно; и в конце концов перестал отвечать совсем.
Анализируя причины, я понял, что основной причиной является высокий порог входа для изучения Spring Security и Shiro, особенно для последнего. Поэтому я решил создать легковесный фреймворк, который бы быстро решал основные проблемы — был бы простым и позволял контролировать права доступа.
### Почему не рассматривается аутентификация (вход)?
На данный момент большинство существующих систем управления правами учитывают "аутентификацию (вход)" + "управление правами". Однако процесс входа в современном мире представляет собой множество различных вариантов, таких как:
* Вход с использованием номера телефона
* Вход через сканирование QR-кода
* Вход с использованием аккаунта и пароля
* Вход с использованием сертификата
Обычно требуется поддерживать несколько методов входа одновременно. Это делает трудным абстрагирование одного общего шаблона для поддержки типичных требований входа.
Поэтому лучше всего не рассматривать эти детали — вопрос входа можно оставить пользователям для самостоятельного решения. Они могут реализовать логику входа в соответствии со своими бизнес-требованиями и выпускать токены, а дальнейшая работа будет выполняться фреймворком `Light Security`. Этот подход более гибкий, и самое важное — вам больше не придётся учиться использовать этот фреймворк для входа.## TODO
* Поддержка конфигурирования симметричного шифрования/несимметричного шифрования;
* Поддержка `JWE`;
* Добавление юнит-тестов;
* Разделение фреймворка и starter'а, чтобы избежать путаницы при использовании как фреймворка, так и starter'а.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )