Наше веб-приложение будет иметь 2 метода Вход в систему: < /p>
- Имя пользователя, пароль и клавиша TOTP (у нас есть это работает) < /li>
Имя пользователя, пароль и Cac/piv card
У нас было несколько идей: < /p>
Идея № 1: Конфигурация сервера < /h3>
Мы нашли несколько других, которые предлагают использовать клиентский аут = «true» Настройка на нашем сервере Tomcat или аналогично. [1] [2] [3] Это было бы идеально, так как это, кажется, самый простой способ реализовать это, но, поскольку нам нужно иметь два метода, упомянутые выше, мы не хотим, чтобы приложение всегда требуется значок.
Здесь примечание- кажется, есть возможность сказать clientAuth = "chany" , что Запрашим сертификат пользователя, но не отказатся от пользователя, который не представит сертификат. Мне все еще нужно узнать, как это работает. (Нельзя рекомендовать использовать "Want" , поскольку это может дать предупреждения в некоторых случаях.)
Другое примечание- Использование clientAuth = "true" или "Want" может оказаться успешным для некоторых, но на самом деле это не предоставляет нам метод, который нам нужен. По сути, он запросит сертификат с того момента, когда сервер загружается. Если установить на "true" , сервер не разрешит доступ к приложению, если он не принимает/не доверяет предоставленный сертификат. Если установить на "Want" , сервер будет искать сертификат, но если ни один из них не найден (или ни один не доверяет), он не будет удерживать их, но просто позволит Пользователь в приложение как обычно. Тем не менее, после этого невозможно запросить сертификат (используя любые настройки сервера).
Чтобы обойти это, мы подумали, что сможем сделать какой -то приложения «Gateway», единственная цель которого состоит в том, чтобы выполнить аутентификацию значка. (Может быть, что -то вроде этого веб -сайта max.gov [4] или других сайтов отделов, связанных на этой странице. Эта реализация на Max.gov - это именно то, что нам нужно: вариант для чтения значков или какой -либо другой метод.) Br /> Мы смогли получить сертификат сервера для использования при тестировании этой идеи! Мы все настроили, и я выяснил Server.xml Конфигурация:
Код: Выделить всё
< /code>
Я все еще учусь, как выполнять работу с нашими требованиями приложения. (См. Мой связанный вопрос [33] о том, как мы получили часть этого процесса для работы. Ссылка [3] была великолепна в объяснении процесса/идеи.)
Идея № 2: Открыто Исходные библиотеки < /h3>
Используйте библиотеку с открытым исходным кодом от Github. Мы нашли несколько источников, которые рекомендуют их: < /p>
[*] [b] opensc < /strong> [5]: этот государственный сайт [6] также относится к нему , Но это кажется каким-то веб-расширением , но оно написано в основном в c. 7]: Мы не уверены, как его использовать. ] Но кажется, что это для настольных приложений-это правда? А некоторые сказали, что это может быть медленным? и ответ на ссылке № 9 использует сервлеты, которые не используются в приложениях Spring Boot (насколько я могу судить).
[*] javax .smartcardio [/b]: эта библиотека, смарт -карта io [20], имеет несколько полезных функций, но есть два недостатка: 1) нет необходимости для всех смарт -карт следовать одни и тем же командам/форматами APDU, и 2) У него возникают проблемы, работающие правильно, когда веб -приложение развернуто на сервере, то есть оно не может найти какую -либо карту или читатель. < /li>
< /ul>
мы читаем о некоторых Использование Java Applets, но это были старые дискуссии. Кроме того, вам, возможно, придется работать с подписанием апплета, а апплеты считаются несколько небезопасными или неуверенными. Более подробно в внедрении аутентификации CAC/PIV -карты, я понял, что ответ, приведенный на ссылке [11] Пользователи используют SmartCard или CAC, и просто начните с идеи, что вы собираетесь использовать сертификаты клиентов для аутентификации. » .
По сути, я узнал, что вам нужен URL-адрес HTTPS для вашего веб-приложения, чтобы ваш сервер мог установить соединение SSL/TLS-это единственный способ Вы можете запросить сертификат пользователя. Если вы получите это, теоретически, вам просто нужно запросить сертификат пользователя x509 с чем -то подобным this:
X509Certificate[] x509certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
if (x509certs != null && x509certs.length > 0) {
X509Certificate x509cert = x509certs[0];
try {
x509cert.checkValidity();
} catch (Exception e) {
System.out.println("error checking cert or cert is not valid.");
}
} else {
System.out.println("certs list is null or empty.");
}
Кроме того Для тех, кто создает заявку на правительственную организацию, вы можете связаться с командой Login.gov на их сайте [17]. Если у вас или вашего агентства есть адрес электронной почты .gov, вы сможете создать учетную запись разработчика и использовать их систему для выполнения аутентификации пользователя. < /P>
Идея № 4: Прямая карта Коммуникация < /h3>
CAC, PIV и другие карты считаются смарт -картами. Компьютеры общаются со смарт -картами через APDUS (блоки данных протокола приложения) [18]. Есть некоторые библиотеки с открытым исходным кодом, которые могут работать, и у Oracle также есть некоторые вещи: Java Card [19], Smart Card IO [20]. API карты Java предназначена в основном для создания и изменения карт и, как правило, использует апплеты, что на самом деле не является хорошим выбором для нас. Карта присутствует и читайте карту ATR: < /p>
Код: Выделить всё
try {
// get all terminals
TerminalFactory factory = TerminalFactory.getDefault();
List terminals = factory.terminals().list();
System.out.println("Terminals: " + terminals);
// get the first terminal
CardTerminal cdTerminal = terminals.get(0);
try {
if (cdTerminal.isCardPresent()) {
// establish a connection with the card
Card card = cdTerminal.connect("*"); // don't limit the type, just in case your card is different
System.out.println("card: " + card);
ATR atr = card.getATR();
System.out.println("ATR: " + atr.getBytes().toString());
card.disconnect(false);
} else {
System.out.println("No card inserted!");
}
} catch (CardException e) {
System.out.println("Failed to determine if card is present.");
}
} catch (CardException e1) {
System.out.println("Failed in smart card io.");
}
Эта библиотека имеет несколько полезных функций, но, к сожалению, есть две недостатки: < /p>
У всех смарт -карт нет требований следовать одни и тем же командам APDU/форматы
[*] У библиотечных функций возникают проблемы, работающие правильно, когда веб -приложение развернуто на сервере, то есть, то есть он не может найти какую -либо карту или читатель. [23], и другие, которые я видел, рекомендуют API Sun PKCS#11, но, очевидно, это устарело. Существуют возможные альтернативы (Bouncy Castle и IAIK PKCS#11 [28]), но все они требуют дополнительных, местных библиотеки PKCS#11.
Другие идеи:
Мне нравится обсуждение здесь [11], но это немного более теоретически без какого -либо примера кода. Несмотря на это, если кто -то еще смотрит на способ выполнить аутентификацию этой значки, ответ там имеет лучшую основу для понимания того, как на самом деле работает аутентификация значков! 12] [13], но на них нет ответов. Слышал, что это не самое лучшее в использовании в приложении Spring Boot . Теперь я немного больше заглядываю на это, чтобы увидеть, что я мог бы использовать (особенно для проверки, присутствует ли карта). < /P>
Существует также руководство по разработчику [15] Для чтения карты, который используется конечным пользователями этого приложения, но мне еще предстоит найти что-то полезное. Поскольку у них теперь есть возможность для методов аутентификации PIV Card [16]. Тем не менее, кажется, что Okta является платной службой, которая не будет для нас вариантом. но это также, по-видимому, требуют команд APDU (которые могут быть в зависимости от карты).
edits
5-14-2024 : Мы больше не будем использовать структуру Spring Boot из -за времени, которое потребуется для преобразования старого кода JDBC в новый путь, используя бон jdbctemplate . Мы также рассматриваем как Tomcat 9, так и для 10 (для двух разных приложений, оба с одинаковыми требованиями входа в систему).
5-30-2024 : у меня есть Провели больше исследований и нашел много хороших идей, но пока ничего не было полностью успешным. Я добавил заметки выше. Смарт -карта! , к сожалению, некоторые детали не работают для меня так же, как описанные источники: я не получаю поле выбора всплывающего сертификата. Это [31], поэтому обязательно проверьте их, если вы нашли мой вопрос полезным!
Код: Выделить всё
// there are various types and providers, but these were the ones that worked
KeyStore keyStore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
// load local certificates (the certificates visible in your browser)
keyStore.load(null);
// get all the names of the available certificates
Enumeration aliases = keyStore.aliases();
Код: Выделить всё
String als;
Certificate cert;
while (aliases.hasMoreElements()) {
als = aliases.nextElement();
System.out.println("Alias: " + als);
cert = keyStore.getCertificate(als); // get the certificate
// check the certificate
certs = keyStore.getCertificateChain(als); // get the certificate chain
// check the certificate chain
}
[*] Попытка использовать SmartCard для аутентификации Tomcat
[*]https://blog.e-zest.com/enable-tomcat-server -for-smart-card-authentication
[*]https://login.max.gov/cas/login?bypassmaxsso=tru /github.com/opensc/opensc
[*]https://www.idmanagement.gov/implement/scl-firefox/
[*] https: // github.com/wicg/web-smart-card
[*]https://stackoverflow.com/a/3826528/1581117
[*] Общая карта доступа ( CAC) Аутентификация с использованием приложения VAADIN
[*] DOD PKI CAC аутентификация в Tomcat (встроенное в jboss)
[*] Аутентификация CAC в java webapp < Br /> [*] Аутентификация CAC на сервере Tomcat < /li>
Аутентификация пользователя, использующего CAC (карта общего доступа) в веб -приложении, работающем в пристани для приложения, используемого правительственным агентством США < / li>
https://marcioreis.pt/how-to-communicat ... g-node-js/
[*] https: //www.hidglobal.com/documents/omnikey-542 ... -developer guide
Использование отлично-идентификации-проверки-piv-credentials-to-enable-passwordless-uthentication/
[*]https://developers.login.gov/
< li> https://en.wikipedia.org/wiki/smart_car ... _data_unit
[*]https://docs.oracle.com/java/javacard/3 ... lass/Index. html
[*]https://docs.oracle.com/javase/8/docs/j ... mmary.html
https://docs.oracle.com/javase/8/docs/j ... nt-byte:a-
[*] Как получить цепочку сертификатов сервера, затем убедитесь, что она действительна и доверяет Java
[*] API для чтения сертификата смарт -карты в Java
[*]https://forums.oracle.com/ords/apexds/p ... mmand-4285
[*]https://forums.oracle.com /ords/apexds/post/use-secure-pin-commands-with-javax-smartcardio-1045
[*] https://stackoverflow.com/a/40673167/15811117
[*]https://github.com/jnasmartcardio/jnasm ... ardio.java
Как инициализировать pkcs11 Поставщик без использования sunpkcs11? /> Загрузите магазин ключей Java для одного псевдонима? Меню для выбора сертификата пользователя в сервере Tomcat 10? )
Подробнее здесь: https://stackoverflow.com/questions/783 ... java-tomca