TokenStore: интерфейс сохраняемости для токенов OAuth2 (для интерфейса сохраняемости токенов OAuth2).
официальная документация
Существует три реализации TokenStore по умолчанию:
- InMemoryTokenStore
- JdbcTokenStore
- JwtTokenStore
Кроме того, под особенности TokenStor будет настроена еще одна реализация — RedisTokenStore.
1. InMemoryTokenStore
1.1. Обзор
Это реализация OAuth2 по умолчанию. Он может показать хорошие результаты для отдельной службы (то есть параллелизм невелик, и его резервная копия не будет создаваться в случае сбоя), и этот метод можно использовать в большинстве проектов. Судя по названию, он хранится в памяти, ведь он существует в памяти, а не на диске, и отлаживать его несложно.
1.2. Реализация
Поскольку InMemoryTokenStore является реализацией OAuth2 по умолчанию, нам не нужно его настраивать, просто вызовите его напрямую.
1.3. Вызов кода
@Autowired(required = false)
private TokenStore inMemoryTokenStore;
/**
* 端点(处理入口)
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(inMemoryTokenStore);
....
}
1.4. Доступ к тестовому звонку для получения токена
Вот небольшая демонстрация, основанная на SpringBoot+Security, и соответствующая конфигурация не будет слишком много упоминаться в этой статье, сосредоточив внимание на TokenStore.
- Spring Security Конечная точка аутентификации авторизации по умолчанию: oauth/token
- Используется здесь: grant_type—>режим пароля
2. JdbcTokenStore
2.1. Обзор
Это реализация на основе JDBC, и токен (токен доступа) будет сохранен в базе данных. Таким образом, совместное использование токенов может быть достигнуто между несколькими службами.
2.2. Реализация
1). Поскольку это JDBC, ему нужен источник данных. Здесь используется SpringBoot, поэтому настроен источник данных. Не так много, чтобы сказать о необходимых зависимостях jar.
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/security?useUnicode=yes&characterEncoding=UTF-8
username: catalpaFlat
password: catalpaFlat
2).Помимо источника данных,тогда у jdbc должна быть библиотечная таблица,поэтому OAuth2 отдает структуру таблицы по умолчанию
Drop table if exists oauth_access_token;
create table oauth_access_token (
create_time timestamp default now(),
token_id VARCHAR(255),
token BLOB,
authentication_id VARCHAR(255),
user_name VARCHAR(255),
client_id VARCHAR(255),
authentication BLOB,
refresh_token VARCHAR(255)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Drop table if exists oauth_refresh_token;
create table oauth_refresh_token (
create_time timestamp default now(),
token_id VARCHAR(255),
token BLOB,
authentication BLOB
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
А операций над таблицей в исходном коде JdbcTokenStore много:
3).Настройте JdbcTokenStore
@Autowired
private DataSource dataSource;
/**
* jdbc token 配置
*/
@Bean
public TokenStore jdbcTokenStore() {
Assert.state(dataSource != null, "DataSource must be provided");
return new JdbcTokenStore(dataSource);
}
2.3. Вызов кода
@Autowired(required = false)
private TokenStore jdbcTokenStore;
/**
* 端点(处理入口)
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(jdbcTokenStore);
....
}
2.4. Доступ к тестовому звонку для получения токена
3. JwttokenStore.
3.1 Обзор
Полное имя jwt — JSON Web Token. Этой реализации не важно, как она хранится (в памяти или на диске), потому что она может кодировать соответствующие информационные данные в маркере. JwtTokenStore не хранит никаких данных, но играет ту же роль, что и DefaultTokenServices, в преобразовании значений токенов и информации об авторизации.
3.2. Реализация
Поскольку jwt хранит информацию в токенах, необходимо учитывать его безопасность, поэтому OAuth2 предоставляет реализацию JwtAccessTokenConverter, добавляя jwtSigningKey для генерации секретного ключа для подписи, и только jwtSigningKey может получить информацию.
/**
* jwt Token 配置, matchIfMissing = true
*
* @author : CatalpaFlat
*/
@Configuration
public class JwtTokenConfig {
private final Logger logger = LoggerFactory.getLogger(JwtTokenConfig.class);
@Value("${default.jwt.signing.key}")
private String defaultJwtSigningKey;
@Autowired
private CustomYmlConfig customYmlConfig;
public JwtTokenConfig() {logger.info("Loading JwtTokenConfig ...");}
@Bean
public TokenStore jwtTokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
String jwtSigningKey = customYmlConfig.getSecurity().getOauth2s().getOuter().getJwtSigningKey();
Assert.state(StringUtils.isBlank(jwtSigningKey), "jwtSigningKey is not configured");
//秘签
jwtAccessTokenConverter.setSigningKey(StringUtils.isBlank(jwtSigningKey) ? defaultJwtSigningKey : jwtSigningKey);
return jwtAccessTokenConverter;
}
}
3.3. Вызов кода
@Autowired(required = false)
private TokenStore jwtTokenStore;
@Autowired(required = false)
private JwtAccessTokenConverter jwtAccessTokenConverter;
/**
* 端点(处理入口)
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(jwtTokenStore)
.accessTokenConverter(jwtAccessTokenConverter);
....
}
3.4. Доступ к тестовому звонку для получения токена
4. RedisTokenStore
4.1 Обзор
Поскольку функция TokenStore заключается в сохранении интерфейса для токенов OAuth2, в фактической разработке мы осторожно относимся к использованию памяти, а хранилище в базе данных также настраивается в соответствии с требованиями проекта. Поэтому я подумал, можем ли мы использовать Redis для хранения и сохранения наших токенов OAuth2. Взглянув на OAuth2 и тех, кто реализует TokenStore, я нашел RedisTokenStore.
4.2. Реализация
Не забудьте настроить Redis
@Autowired
private RedisConnectionFactory redisConnectionFactory;
/**
* redis token 配置
*/
@Bean
public TokenStore redisTokenStore() {
return new RedisTokenStore(redisConnectionFactory);
}
4.3. Вызов кода
@Autowired(required = false)
private TokenStore redisTokenStore;
/**
* 端点(处理入口)
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(redisTokenStore);
....
}