Microsoft создала систему для управления токеном сразу на нескольких блокчейнах

Доброго дня, уважаемые коллеги! Мучаюсь несколько дней, не смог решить проблему, поэтому взываю о помощи Пикабу 🙂

Итак –

Есть флешка (токен) сбербанка бизнес онлайн, есть комп с Windows 10 Pro.

На токене, чтобы запустить страницу входа банк, нужно запустить приложение start.exe.

Браузером по умолчанию в системе был назначен Chrome (мозиллу тоже пробовал).

Так вот, при запуске приложения start.exe, система открывает страницу входа через….internet explorer 11, абсолютно игнорируя примененные настройки браузера по умолчанию.

Почему нужен chrome – при обмене с банком в обе стороны создается файл kl_to_1c.txt

При дублировании этого файла в одной папке explorer создает такой же, только с постфиксом (1), и соответственно ни банк, ни 1С в автоматическом режиме его не видят.

В хроме эта проблема решалась установкой расширения из магазина приложений, которое заставляло его перезаписывать, а не создавать похожий.

в Win7 таких проблем не было – все открывалось через установленный по умолчанию браузер.

что с 10-кой не так – не пойму)

Памажыте пожалуйста)

–>

применимо к: Windows server 2022, Windows server 2019, Windows Server 2016 и Windows 10

Протокол привязки токенов позволяет приложениям и службам криптографически привязывать свои маркеры безопасности к уровню TLS для устранения атак с кражой и воспроизведением маркеров. Долгосрочные, однозначно идентифицируемые привязки TLS [RFC5246] могут охватывать несколько сеансов TLS и соединений.

Поддерживаемые версии:

  • Windows 10, версия 1507 – Отключено по умолчанию
    • Добавлен протокол привязки маркеров [черновик-IETF-токбинд-Protocol-01]
    • WinInet & HTTP.SYS поддержку привязки маркеров по протоколу HTTP &
  • Windows 10, версии 1511 и 1607 и Windows Server 2016 по – умолчанию
    • Протокол привязки токена обновлен [черновик-IETF-токбинд-Protocol-01]
    • Расширение TLS для согласования привязки токена Добавлено [черновик-Попов-токбинд-переговоры-00]
    • WinInet & HTTP.SYS поддержка привязки маркера по протоколу HTTP обновлена &
  • Windows 10, версия 1507 с обслуживанием update KB4034668, Windows 10, версия 1511 с обслуживанием update KB4034660, Windows 10, версия 1607 и Windows Server 2016 с обслуживанием обновления KB4034658 протокол привязки маркеров, версия 0,10 включена по умолчанию
    • Протокол привязки токена обновлен [черновик — IETF-токбинд-Protocol-10]
    • Добавлено расширение TLS для согласования привязки маркеров [черновик-IETF-токбинд-переговоры-05]
    • WinInet & HTTP.SYS поддержка привязки маркера по протоколу HTTP обновлена &
  • Windows 10, версия 1703 поддерживает протокол привязки маркеров версии 0,10 – Включено по умолчанию
    • Протокол привязки токена обновлен [черновик — IETF-токбинд-Protocol-10]
    • Добавлено расширение TLS для согласования привязки маркеров [черновик-IETF-токбинд-переговоры-05]
    • WinInet & HTTP.SYS поддержка привязки маркера по протоколу HTTP обновлена &
    • Windows устройства с включенной безопасностью на основе виртуализации будут поддерживать ключи привязки маркеров в защищенной среде, изолированной от работающей операционной системы.

сведения о поддержке ASP .net можно найти в источнике ссылки на платформа .NET Framework.

дополнительные сведения о платформа .NET Framework см. в следующих разделах:

  • Улучшения работы с сетью

  • Класс .NET Токенбиндинг

–>

Токен — это устройство в виде USB-флешки с защищенной паролем картой памяти, на которой хранится информация для создания подписи. Токен обеспечивает двухфазную аутентификацию пользователя: для работы необходимо вставить токен в USB-разъем компьютера и ввести пароль.

В России два вида токенов:

  • Рутокен – ключевой носитель, разработанный и широко применяемый в России. Продукты на базе Рутокена широко используются в коммерческих и государственных проектах. Кроме того, безопасность рутокенов постоянно повышается — в частности, в новых версиях операции шифрования документа выполняются не только на компьютере, но и в самом устройстве. Это делает электронную подпись более защищенной от вирусов и хакерских атак.
  • Е-токен – европейский вариант ключевого носителя. Е-токены могут содержать практически любой дополнительный чип RFID (радио-метку) для интеграции с системами контроля и управления доступом в помещения.

Только СКБ Контур выпускает электронные подписи со встроенной лицензией. Это позволяет подписывать файлы с любого рабочего места — лицензия СКЗИ уже есть на токене. Команды СКБ Контур и Рутокена взаимодействовали на этапе разработки, благодаря чему пользователи наших услуг получают качественный и удобный носитель, который легко устанавливать и использовать.

УЦ СКБ Контур выпускает все виды электронных подписей.

В Spring Security JWT-токен используется в OAuth 2 как access token. Он выдается клиенту сервером авторизации, клиент отправляет его при обращении к серверу ресурсов. (А сервер ресурсов проверяет его, обращаясь к серверу авторизации).

Но этот пример — самописная реализация stateless REST API на JWT, единое приложение, которое и выдает, и проверяет токен. И выдает REST API.

На этом примере можно увидеть, как написать свой фильтр авторизации, как сформировать и проверить JWT-токен. Но в реальном проекте этот пример лучше не использовать.

Если нужен JWT без OAuth2, то есть в Spring Boot есть и такое готовое решение.

Задача

В этой статье  будет чистый REST-сервис без фронтенда. Подразумевается, что фронтенд написан отдельно: например, на каком-нибудь JavaScript-фрейворке.

Для отправки запросов мы будем использовать программу POSTMAN. Например, для «входа» с именем/паролем и получения JWT-токена. А также для запроса защищенных страниц.

В этом примере наш старый REST-контроллер останется, а настройка Spring Security не особо поменяется — скорее, она дополнится.

  1. Мы добавим в приложение конечную точку /authenticate для аутентификации. Сюда приходят имя и пароль от пользователя. Приложение проверяет пароль, и если он верный, высылает пользователю в ответ JWT-токен.
  2. Во всех дальнейших запросах пользователь обязан высылать в заголовке JWT-токен, наше приложение проверяет подлинность токена в специально написанном фильтре JWTFilter и, если он корректен, пропускает запрос дальше.

Подготовка

REST-контроллер

Итак, наш основной REST-контроллер остается прежним:

@RestController  public class HelloController {        @GetMapping("/")      public String hello() {          return "Hello";      }        // сюда доступ разрешен только user и admin       @GetMapping("/user")      public String user() {          return "User";      }        // сюда доступ разрешен только admin       @GetMapping("/admin")      public String admin() {          return "Admin";      }    }  

Он нужен для того, чтобы запретить к нему доступ и потом разрешить только авторизованным пользователям.

Аутентификация с пользовательским UserDetailsService

Настройка аутентификации такая:

@EnableWebSecurity  public class SecurityConfig extends WebSecurityConfigurerAdapter {      @Autowired      private CustomUserDetailsService userDetailsService;        @Bean      public PasswordEncoder passwordEncoder() {          return NoOpPasswordEncoder.getInstance();      }        //...         @Override      public void configure(AuthenticationManagerBuilder auth) throws Exception {          auth.userDetailsService(userDetailsService);      }    }  

Подробнее об аутентификации с UserDetailsService есть статья.

Если кратко, мы переопределяем метод loadUserByUsername(), чтобы Spring Security понимал, как взять пользователя по его имени из хранилища. Имея этот метод, SS может сравнить переданный пароль с настоящим и аутентифицировать пользователя (либо не аутентифицировать).

CustomUserDetailsService:

@Service  public class CustomUserDetailsService implements UserDetailsService {      @Autowired      private MyUserRepository dao;      @Override      public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {          MyUser myUser= dao.findByLogin(userName);          if (myUser == null) {              throw new UsernameNotFoundException("Unknown user: "+userName);          }          UserDetails user = User.builder()                  .username(myUser.getLogin())                  .password(myUser.getPassword())                  .roles(myUser.getRole())                  .build();          return user;      }  }  

Пользователи хранятся в In-Memory базе данных H2. Работаем через Hibernate.

Модель пользователя:

@Entity  public class MyUser {      @Id      @GeneratedValue(strategy = GenerationType.IDENTITY)      long id;      private String login;      private String password;      private String position;      private String role;         // геттеры/сеттеры    }

И репозиторий:

@Repository  public interface MyUserRepository extends JpaRepository {      MyUser findByLogin(String login);  }

А данными заполняем базу на старте приложения с помощью data.sql (этот файл надо положить в папку /resources, а в application.yml включить его запуск):

insert into my_user(login, position, password, role) values('user', '1', 'password', 'USER');  insert into my_user( login, position, password, role) values('admin', '2', 'password', 'ADMIN');

А теперь перейдем собственно в JWT-токену.

Библиотека для работы с JWT-токеном

Для работы с JWT добавим Maven-зависимость:

  io.jsonwebtoken jjwt 0.9.1 

Для работы с JWT-токеном уже написаны утилиты, так что используем готовую. В ней есть метод формирования токена, методы извлечения имени пользователя и других данных. Метод формирования токена изменим так, чтобы записывать в токен еще список authorities в виде клейма authorities.

Во всех методах извлечения данных JWT-токен заодно проверяется на предмет не истек ли он, и валидна ли подпись.

Эти методы утилиты нам пригодятся:

@Service  public class JWTUtil {        @Value("${jwt.secret}")      private String SECRET_KEY;        @Value("${jwt.sessionTime}")      private long sessionTime;        // генерация токена (кладем в него имя пользователя и authorities)      public String generateToken(UserDetails userDetails) {          Map claims = new HashMap<>();          String commaSeparatedListOfAuthorities=  userDetails.getAuthorities().stream().map(a->a.getAuthority()).collect(Collectors.joining(","));          claims.put("authorities", commaSeparatedListOfAuthorities);          return createToken(claims, userDetails.getUsername());      }            //извлечение имени пользователя из токена (внутри валидация токена)      public String extractUsername(String token) {          return extractClaim(token, Claims::getSubject);      }        //извлечение authorities (внутри валидация токена)      public String extractAuthorities(String token) {         return extractClaim(token, claims -> (String)claims.get("authorities"));      }     // другие методы  }

Это была подготовка. Перейдем, наконец, к написанию своего кода, касающегося JWT.

Конечная точка аутентификации для выдачи JWT-токена

Тут собственно выдается  JWT-токен. Пользователь делает POST-запрос с именем и паролем по адресу /authenticate, а в ответ получает сгенерированынй токен. Токен генерится методом generateToken() из утилиты выше.

@RestController  public class AuthenticationController {          @Autowired      private AuthenticationManager authenticationManager;        @Autowired      private JWTUtil jwtTokenUtil;          @PostMapping("/authenticate")      @ResponseStatus(HttpStatus.OK)      public AuthResponse createAuthenticationToken(@RequestBody AuthRequest authRequest) {          Authentication authentication;          try {              authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(authRequest.getName(), authRequest.getPassword()));              System.out.println(authentication);          } catch (BadCredentialsException e) {              throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Имя или пароль неправильны", e);          }          // при создании токена в него кладется username как Subject claim и список authorities как кастомный claim          String jwt = jwtTokenUtil.generateToken((UserDetails) authentication.getPrincipal());            return new AuthResponse(jwt);      }  }  

Запрос имеет такой формат:

public class AuthRequest {      private String name;      private String password;      // геттеры сеттеры  }

А ответ такой:

public class AuthResponse {        private String jwtToken;       // геттер и сеттер  }

Если имя и пароль верные, токен возвращается в AuthResponse, а если нет — выбрасывается исключение и на фронтенд приходит сообщение об ошибке.

Фронтенд сохраняет у себя JWT-токен, и потом использует его при каждом запросе.

Немного о «разлогине»

Если пользователь хочет выйти, токен должен быть уничтожен на фронтенде. На бэкенде (в нашем Spring приложении) он продолжит действовать до истечения своего срока. А вообще теоретически можно сделать черный список токенов, но не в этом примере.

Еще: чтобы сделать токены сразу всех пользователей недействительными, достаточно поменять секретный код. Но тогда разлогинены будут все сразу.

В этом проблема JWT-токена  — нужны обходные пути для того, чтобы сделать его недействительным.

Перейдем ко второй принципиальной части — фильтру, проверяющему токен при каждом запросе.

Фильтр, проверяющий JWT-токен при каждом запросе

Итак, JWT-токен выдан, клиент его нам отправляет при каждом запросе, надо этот токен при каждом запросе проверять (и извлекать из него имя пользователя). Для этого напишем фильтр JWTFilter. Он расширяет OncePerRequestFilter и происходит в нем следующее:

  1. При каждом запросе из заголовка Authorization берем JWT-токен (он начинается с  префикса «Bearer«).
  2. Извлекаем из него имя пользователя (claim subject) и список authorities (claim authorities). Оба клейма мы записывали в токен при его генерации в контроллере.
  3. Одновременно при извлечении claims проверяется валидность токена. Для этого не надо делать никаких запросов в базу: достаточно самого токена и jwt.secret (прописанного в application.yml). На основе этого секрета токен генерился, и на основе него он потом каждый раз проверяется с помощью хеш-функции (это делает библиотека jjwt).
  4. Если все ок, то имея имя пользователя и список authorities (извлеченные в п.2), создаем объект Authentication (точнее, его подкласс UsernamePasswordAuthenticationToken). И устанавливаем объект Authentication  в SecurityContext. Так нужно для Spring Security.
  5. Если с токеном не все ок, то в п. 2-3 выбросился исключение, и  фильтр не пропустит запрос в контроллер к защищенному /url.
@Component  public class JWTFilter extends OncePerRequestFilter {        @Autowired      private JWTUtil jwtUtil;        @Autowired      CustomUserDetailsService userDetailsService;        @Override      protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)              throws ServletException, IOException {            final String authorizationHeader = request.getHeader("Authorization");            String username = null;          String jwt = null;            if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {              jwt = authorizationHeader.substring(7);              //если подпись не совпадает с вычисленной, то SignatureException              //если подпись некорректная (не парсится), то MalformedJwtException              //если время подписи истекло, то ExpiredJwtException              username = jwtUtil.extractUsername(jwt);          }              if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {                String commaSeparatedListOfAuthorities = jwtUtil.extractAuthorities(jwt);              List authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(commaSeparatedListOfAuthorities);              UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =                      new UsernamePasswordAuthenticationToken(                              username, null, authorities);                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);            }          chain.doFilter(request, response);      }    }  

Настройка авторизации: собираем все вместе

Тут все как раньше, но только:

  1. отключаем csrf,
  2. отключаем сессии
  3. и добавляем наш фильтр JWTFilter перед фильтром UsernamePasswordAuthenticationFilter.
@EnableWebSecurity  public class SecurityConfig extends WebSecurityConfigurerAdapter {            @Autowired      private JWTFilter jwtFilter;       // еще поля и методы         // Бин AuthenticationManager используется в контроллере аутентификации (см. выше)        @Bean      public AuthenticationManager authenticationManagerBean() throws Exception {          return super.authenticationManagerBean();      }        // тут отключаем сессии и добавляем фильтр JWTFilter         @Override      protected void configure(HttpSecurity http) throws Exception {          http.csrf().disable()                  .authorizeRequests()                  .antMatchers("/authenticate").permitAll()                  .and().authorizeRequests().antMatchers("/user/**").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN")                  .and().authorizeRequests().antMatchers("/admin/**").hasAuthority("ROLE_ADMIN")                  .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);            http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);      }  }  

Проверка

Запустим приложении и убедимся, что все работает.

Получение JWT-токена

Отправим POST-запрос нужного формата по адресу /authencate:

image
Этим запросом получаем jwt-токен

Отправка запроса с JWT-токеном

Токен получен, теперь с ним можно попасть на защищенную страницу. Для этого добавим его к запросу /user в заголовок Authorization.

При этом выберем тип Bearer-токен — это значит, что префикс Bearer будет добавлен к токену.

А теперь с ним запрашиваем защищенный url /user

Как видно, страница /user получена.

Вид JWT-токена

Если декодировать токен на сайте https://jwt.io/, то в нем видны наши добавленные клеймы sub (имя пользователя) и authorities:

Декодированный токен

Остальные два клейма:

  • exp — когда истекает токен
  • iat -когда выпущен токен

Исходный код

Он находится на GitHub.

image

Пользователи социальных сетей привыкли использовать логин и пароль в качестве данных для авторизации в сервисах. Другие идут дальше и предпочитают использовать QR-код для входа. Однако оба этих метода слишком муторны и неудобны, когда необходимо подключить к аккаунту бота или авторизоваться в сервисе через стороннее приложение. В таком случае в Дискорд на помощь приходят токены. Расскажем, как использовать токен в Дискорде и что делать, если он устарел.

Итак, если вас заинтересовала тема работы с токенами, то, скорее всего, вам:

  • Необходимо авторизоваться через сторонний сервис в Дискорде, а стандартные логин и пароль не принимаются.
  • Необходимо разработать бота для сервера в Дискорде. Скорее всего, это ваш первый бот, так как тема использования token изучается в самом начале.
  • Нужно разработать собственное приложение, в котором происходит авторизация через Дискорд.

image

В ином случае вам просто интересно значение этого термина, так как оно часто мелькает в материалах про компьютеры. В любом случае, у самого термина есть только одно определение.

Токен – это своеобразный идентификационный ключ, позволяющий авторизоваться или подключиться к какому-то аккаунту. В отличие от логинов и паролей, токен – это одна большая генерируемая строка, а не две пользовательские.

image

Еще одна отличительная особенность token-ов в том, что их срок действия и права доступа легко настраивать, да и они одноразовые (не всегда). Например, планируется выдать доступ только к имени аккаунта и только на 24 часа, выставляете эти настройки в параметрах, и вуаля: token с пользовательскими настройками готов.

Впрочем, описание выше относится к самому термину «токен». В Дискорде термин «token» означает своеобразный ключ аутентификации, который позволяет обращаться к созданному боту (при его разработке) либо проходить авторизацию в сторонних сервисах. Существуют даже token grabber-ы, которые позволяют считать данные с аккаунта.

И еще, даже если данные попадут в какую-то пиратскую базу, то их можно отозвать или сбросить. В общем, преимущество токенов в их компактности и безопасности.

image

Итак, чтобы получить token для бота, необходимо сначала создать этого бота. Для этого вам понадобится владеть навыками программирования. Впрочем, опустим пункт с разработкой. Вот, у вас есть готовый бот, который осталось подключить к Дискорду с помощью token-а. Для этого выполняем следующие действия:

  • Откройте сайт Дискорда для разработчиков. Он находится по этой ссылке https://discord.com/developers/applications

image

  • Нажмите кнопку «New Application».
  • Выберите название нового приложения.

image

  • Заполните нужные данные для бота. Там нужно указать его описание, а также статус. Однако, все это опционально.
  • Перейдите в раздел «Bot».
  • Найдите заголовок поля «Token». Под ним будет ссылка «Click to Reveal token». Нажмите на нее.
  • Вместо ссылки отобразится длинный текст, состоящий из символов и цифр.

image

Поздравляем, вы нашли токен для вашего бота. Теперь осталось указать этот токен в коде. К слову, чтобы добавить бота на сервер, токен не поможет, нужно получать специальную ссылку, которая находится в том же разделе. Кстати, здесь же можно сбросить старый токен и сгенерировать новый. Для этого нажмите на синюю кнопку «Regenerate». Учтите, что после этого старый токен потеряет актуальность, а потому боты на серверах перестанут работать.

Способ выше отлично подходил, если необходимо было получить токен для подключения к одному боту. А что делать, если вместо бота нужно подключиться к собственной учетной записи? В таком случае придется воспользоваться другим методом. Алгоритм действий:

  • Откройте главную страницу Дискорда в браузере. Через устанавливаемую версию ничего сделать не получится.
  • Нажмите кнопку «F12» (или «Ctrl» + «Shift» + «I»). Должны открыться инструменты разработчика.

image

  • Перейдите в раздел «Сеть» («Network»).
  • Введите в окно поиска фразу «/api/v9».
  • Откройте любой найденный файл.
  • Перейдите в раздел «Заголовки» («Headers»). По умолчанию там выбран «Предварительный просмотр», если вы сидите с Google chrome.
  • Прокрутите его до строки «Authorization». После нее будет указан ваш токен.
  • Скопируйте его.

Готово. Теперь вы можете указать его в нужном поле для авторизации. Учтите, что токен равносилен данным авторизации, а потому его не стоит оставлять на виду у всех.

Итак, зайти напрямую через токен не получится. Он не отправляется GET-запросом, а значит, просто скопировать текст в строку URL нельзя. Однако не стоит разочаровываться и возмущаться, зачем эти инструкции выше. Token часто используется сторонними сервисами для авторизации.

При необходимости вы можете скопировать идентификационный текст именно туда. Но учтите, токен привязан к одной сессии в Дискорде. То есть, если пользователь нажмет кнопку «Выйти», token автоматически станет недействительным.

На просторах интернета довольно часто предлагают приобрести токен за небольшую круглую сумму. С одной стороны, почему бы не взять, ведь это выгодно, цена-то практически мизерная. Но не ведитесь на это, так как большинство таких предложений исходят от мошенников. Оставшаяся доля продавцов может продать токен, но только не ваш, а чей-то. Да и он перестанет быть действительным, когда владелец сбросит настройки или завершит сессию.

Запомните, все token-ы ваших ботов и аккаунтов получаются бесплатным путем и без посредников. Не стоит верить этим банальным схемам мошенников.

Вы строго следовали инструкциям выше и, кажется, все получилось, авторизация через Дискорд прошла успешно, бот подключен и все вроде бы идеально. Однако через время вдруг эта инструкция уже не работает, а вместо желанного результата появляется ошибка «Токен устарел». Что же делать в таком случае?

Как мы уже говорили выше, эти секретные token-ы легко отозвать. Чтобы сделать это с ботом, достаточно зайти в панель управления приложением, в раздел «Bot» и нажать «Regenerate», а после скопировать новые данные. Готово, осталось закинуть новые данные в код с ботом и радоваться результату.

Чтобы сбросить token для аккаунта, достаточно выйти из профиля на сайте, где производилось копирование token. После авторизуйтесь снова, повторите алгоритм из раздела «Как узнать Дискорд-токен для аутентификации». Новые данные запишите в надежное место, а после скопируйте в настройки сервиса, где появилась ошибка. Как вы уже поняли, устаревший token – это некритичная ошибка, а лишь мера безопасности, спасающая от тех самых мошенников, которые продают аккаунты.

Надеемся, что эти способы помогли вам. Если остались вопросы, то смело задавайте их в комментариях. Благодарим за прочтение.

24.11.2021 20:44 2 Евгений Верещака Информационный портал IT Техник

Оцените статью
Рейтинг автора
4,8
Материал подготовил
Егор Новиков
Наш эксперт
Написано статей
127
А как считаете Вы?
Напишите в комментариях, что вы думаете – согласны
ли со статьей или есть что добавить?
Добавить комментарий