JwtPermission
Обновление журнала
2020-01-14 (v3.1.1)
2019-12-16 (v3.0.0)
1. Введение
Основанный на токенах Java Web-фреймворк контроля разрешений, использующий jjwt, поддерживающий redis и db в качестве различных способов хранения данных, подходящий для проектов с разделением переднего и заднего плана, функциональный, простой в использовании и расширяемый. Подробная документация по разработке
2. Использование
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>jwtp-spring-boot-starter</artifactId>
<version>3.1.1</version>
</dependency>
Добавьте аннотацию @EnableJwtPermission в класс запуска приложения.
## 0 — это redisTokenStore, 1 — jdbcTokenStore, по умолчанию 0
jwtp.store-type=0
## Путь перехвата, по умолчанию /**
jwtp.path=/**
## Исключённый путь перехвата, по умолчанию нет
jwtp.exclude-path=/login
## Максимальное количество токенов для одного пользователя, по умолчанию -1 без ограничений
jwtp.max-token=10
## Режим соответствия URL и разрешений, 0 — упрощённый режим, 1 — RESTful режим
# jwtp.url-perm-type=0
## Пользовательский SQL для поиска разрешений
# jwtp.find-permissions-sql=SELECT authority FROM sys_user_authorities WHERE user_id = ?
## Пользовательский SQL для поиска ролей
# jwtp.find-roles-sql=SELECT role_id FROM sys_user_role WHERE user_id = ?
## Уровень журнала установлен на debug для вывода подробной информации
logging.level.org.wf.jwtp=DEBUG
Если используется jdbcTokenStore, необходимо импортировать предоставленный фреймворком SQL-скрипт. Если используется redisTokenStore, требуется интегрировать redis.
@RestController
public class LoginController {
@Autowired
private TokenStore tokenStore;
@PostMapping("/token")
public Map token(String account, String password) {
// Ваша логика проверки
// ......
// Выдача токена
Token token = tokenStore.createNewToken(userId, permissions, roles, expire);
System.out.println("access_token:" + token.getAccessToken());
}
}
Описание параметров метода createNewToken:
Подробное описание createNewToken и использование механизма refresh_token см. в подробной документации.
1. Использование аннотаций:
// Требуется разрешение system для доступа
@RequiresPermissions("system")
// Требуется разрешения system и front для доступа, logical можно не указывать, по умолчанию AND
@RequiresPermissions(value={"system","front"}, logical=Logical.AND)
// Требуется разрешение system или front для доступа
@RequiresPermissions(value={"system","front"}, logical=Logical.OR)
// Требуется роль admin или user для доступа
@RequiresRoles(value={"admin","user"}, logical=Logical.OR)
Аннотации добавляются к методам или классам контроллеров.
2. Использование кода:
// Есть ли разрешение system
SubjectUtil.hasPermission(request, "system");
// Есть ли разрешения system или front
SubjectUtil.hasPermission(request, new String[]{"system","front"}, Logical.OR);
// Есть ли роли admin или user
SubjectUtil.hasRole(request, new String[]{"admin","user"}, Logical.OR)
JwtPermistion генерирует исключения при неудачной проверке токена или отсутствии разрешений:
Исключение | Описание | Сообщение об ошибке |
---|---|---|
ErrorTokenException | Ошибка проверки токена | «Ошибка аутентификации», код ошибки 401 |
ExpiredTokenException | Токен уже истёк | «Срок действия входа истёк», код ошибки 402 |
UnauthorizedException | Нет разрешений | «Нет доступа», код ошибки 403 |
Рекомендуется использовать обработчик исключений для перехвата исключений и возврата данных JSON:
@ControllerAdvice
public class ExceptionHandler {
@ResponseBody
@ExceptionHandler(Exception.class)
public Map<String, Object> errorHandler(Exception ex) {
Map<String, Object> map = new HashMap<>();
// Получение сообщения об ошибке в соответствии с различными ошибками
if (ex instanceof TokenException) {
map.put("code", ((TokenException) ex).getCode());
map.put("msg", ex.getMessage());
} else {
map.put("code", 500);
map.put("msg", ex.getMessage());
ex.printStackTrace();
}
return map;
}
}
Добавление аннотации @Ignore к методу или классу контроллера позволяет исключить перехват фреймворка, что означает, что интерфейс не должен передавать access_token.
Примечание: в тексте запроса присутствуют ссылки на внешние ресурсы, которые не были переведены. Если при выдаче токена указаны полномочия и роль, то без повторного получения токена или активного обновления полномочий полномочия и роли не будут обновлены в реальном времени.
Можно настроить SQL-запросы для поиска ролей и полномочий пользователя в реальном времени:
## 自定义 SQL-запрос для поиска полномочий пользователя
jwtp.find-permissions-sql=SELECT authority FROM sys_user_authorities WHERE user_id = ?
## 自定义 SQL-запрос для поиска роли пользователя
jwtp.find-roles-sql=SELECT role_id FROM sys_user_role WHERE user_id = ?
2.5.3. Автоматическое сопоставление полномочий с URL
Если вы не хотите добавлять аннотацию @RequiresPermissions к каждому интерфейсу для управления полномочиями, можно настроить автоматическое сопоставление полномочий по URL:
## Тип сопоставления полномочий по URL, 0 — упрощённый режим, 1 — RESTful режим
jwtp.url-perm-type=0
RESTful режим (метод запроса: URL): post:/api/login
Упрощённый режим (URL): /api/login
После настройки автоматического сопоставления можно также использовать аннотации. Аннотации имеют более высокий приоритет, чем автоматическое сопоставление. Вы также можете использовать Swagger для автоматического сканирования всех интерфейсов и создания таблицы полномочий в базе данных.
2.5.4. Получение информации о текущем пользователе
Обычно информацию о пользователе можно получить следующим образом:
Token token = SubjectUtil.getToken(request);
Для исключённых интерфейсов информацию о пользователе можно получить так:
Token token = SubjectUtil.parseToken(request);
2.5.5. Активное аннулирование токена:
Чтобы удалить определённый токен пользователя:
tokenStore.removeToken(userId, access_token);
Чтобы удалить все токены пользователя:
tokenStore.removeTokensByUserId(userId);
2.5.6. Обновление списка ролей и полномочий
После изменения ролей и полномочий пользователя необходимо синхронизировать обновление ролей и полномочий в системе:
// Обновление списка ролей пользователя tokenStore.updateRolesByUserId(userId, roles);
// Обновление списка полномочий пользователя tokenStore.updatePermissionsByUserId(userId, permissions);
2.6. Передача токена на стороне клиента
Передайте токен через параметр access_token:
$.get("/xxx", { access_token: token }, function(data) {
});
Или передайте токен через заголовок Authorization и Bearer:
$.ajax({ url: "/xxx", beforeSend: function(xhr) { xhr.setRequestHeader("Authorization", 'Bearer '+ token); }, success: function(data){ } });
Контакты
Группа для технического общения между фронтендом и бэкендом:
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )