Краткий обзор Spring Security
Итак, дорогой хабраюзер, предлагаю тебе рассмотреть такие аспекты Spring Security как:
- Ключевые объекты контекста Spring Security.
- Процесс аутентификации в Spring Security.
- Подключение собственно самого Spring Security к проекту.
Ключевые объекты контекста Spring Security:
- SecurityContextHolder, в нем содержится информация о текущем контексте безопасности приложения, который включает в себя подробную информацию о пользователе(Principal) работающем в настоящее время с приложением. По умолчанию SecurityContextHolder используетThreadLocal для хранения такой информации, что означает, что контекст безопасности всегда доступен для методов исполняющихся в том же самом потоке. Для того что бы изменить стратегию хранения этой информации можно воспользоваться статическим методом класса SecurityContextHolder.setStrategyName(String strategy). Более подробно SecurityContextHolder
- SecurityContext, содержит объект Authentication и в случае необходимости информацию системы безопасности, связанную с запросом от пользователя.
- Authentication представляет пользователя (Principal) с точки зрения Spring Security.
- GrantedAuthority отражает разрешения выданные пользователю в масштабе всего приложения, такие разрешения (как правило называются «роли»), например ROLE_ANONYMOUS, ROLE_USER, ROLE_ADMIN.
- UserDetails предоставляет необходимую информацию для построения объекта Authentication из DAO объектов приложения или других источников данных системы безопасности. Объект UserDetailsсодержит имя пользователя, пароль, флаги: isAccountNonExpired, isAccountNonLocked, isCredentialsNonExpired, isEnabled и Collection — прав (ролей) пользователя.
- UserDetailsService, используется чтобы создать UserDetails объект путем реализации единственного метода этого интерфейса
Java Security, Part 1
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
Аутентификация
(1) Пользователю будет предложено войти в систему предоставив имя (логин или email) и пароль. Имя пользователя и пароль объединяются в экземпляр класса UsernamePasswordAuthenticationToken(экземпляр интерфейса Authentication) после чего он передается экземпляру AuthenticationManager для проверки.
(2) В случае если пароль не соответствует имени пользователя будет выброшено исключение BadCredentialsException с сообщением “Bad Credentials”.
(3) Если аутентификация прошла успешно возвращает полностью заполненный экземпляр Authentication.
(4) Для пользователя устанавливается контекст безопасности путем вызова метода SecurityContextHolder.getContext().setAuthentication(…), куда передается объект который вернул AuthenticationManager.
Подключение поддержки Security для SpringFramework приложения:
3.1.4.RELEASE org.springframework.security spring-security-core $ org.springframework.security spring-security-web $ org.springframework.security spring-security-config $
springSecurityFilterChain org.springframework.web.filter.DelegatingFilterProxy springSecurityFilterChain /*
Создание Spring Security REST API с использованием JWT токена
Ну и конечно же сам файл с настройкой security.xml
Пояснение к коду security.xml:
Подразумевается что на странице login.jsp есть форма с action=»/j_spring_security_check» в которой содержаться input’ы для имени и пароля с name=«j_username» и name=«j_password», а также checkbox c name=»_spring_security_remember_me». Это всё специальные значения которые требует Spring Security иначе параметры просто не будут передаваться в контекст безопасности. После успешного прохождения аутентификации пользователь будет перенаправлен на страницу /index где уже применяются правила авторизации. Если не указывать форму и url в http spring-security тогда по умолчанию будет работать basic authentication или можно подключить basic authentication насильно указав в http spring-security
На url /index* доступ могут иметь пользователи с правами ROLE_USER, а также гости (все подключения которые не прошли аутентификацию получают имя guest и права ROLE_ANONYMOUS).
Доступ к url /add* имеют только пользователи с правами ROLE_USER Доступ к url /delete* только пользователи с правами ROLE_ADMIN
Также, авторизованный доступ можно прикручивать на методы, для этого в security.xml нужно добавить, следующий элемент:
и в самом коде:
public interface AdminService
В примере пользователи хранятся списком в .xml файле т.е. сравнение UsernamePasswordAuthenticationToken будет производиться с этими данными. Для того чтобы сравнивать с пользователями в базе данных (используя ORM), нужно реализовать метод loadUserByUsername интерфейса UserDetailsService и указать в ссылку на bean вашей реализации UserDetailsService. Если же вы не используете ORM и вам нужно просто вытянуть из базы пользователей и их права с помощью JDBC, нужно определить DataSource бин с помощью которого Spring будет знать как достучаться до БД и в указать ссылку на этот бин и определить два запроса по которым будут вытягиваться нужные данные users-by-username-query и authorities-by-username-query.
Также может осуществляться проверка хешированных паролей:
Источник: habr.com
Введение в Java SecurityManager
В этом уроке мы рассмотрим встроенную инфраструктуру безопасности Java, которая по умолчанию отключена. В частности, мы рассмотрим его основные компоненты, точки расширения и конфигурации.
2. Менеджер безопасности в действии
Это может быть сюрпризом, но по умолчанию Менеджер безопасности настройки запрещают | многие стандартные операции :
System.setSecurityManager(new SecurityManager()); new URL(«http://www.google.com»).openConnection().connect();
Здесь мы программно включаем контроль безопасности с настройками по умолчанию и пытаемся подключиться к google.com.
Тогда мы получаем следующее исключение:
java.security.AccessControlException: access denied («java.net.SocketPermission» «www.google.com:80» «connect,resolve»)
В стандартной библиотеке есть множество других вариантов использования-например, чтение системных свойств, чтение переменных среды, открытие файла, отражение и изменение языкового стандарта, чтобы назвать некоторые из них.
3. Пример использования
Эта инфраструктура безопасности была доступна с Java 1.0. Это было время, когда апплеты – Java – приложения, встроенные в браузер, – были довольно распространены. Естественно, необходимо было ограничить их доступ к системным ресурсам.
В настоящее время апплеты устарели. Однако обеспечение безопасности по-прежнему является актуальной концепцией, когда возникает ситуация, когда сторонний код выполняется в защищенной среде .
Например, рассмотрим, что у нас есть экземпляр Tomcat, где сторонние клиенты могут размещать свои веб-приложения. Мы не хотим, чтобы они выполняли такие операции, как System.exit () , потому что это повлияло бы на другие приложения и, возможно, на всю среду.
4. Дизайн
4.1. Менеджер по безопасности
Одним из основных компонентов встроенной инфраструктуры безопасности является java.lang SecurityManager . Он имеет несколько методов checkXxx , таких как check Connect , которые разрешали нашу попытку подключиться к Google в приведенном выше тесте. Все они делегируются в checkPermission(java.security.Разрешение) метод.
4.2. Разрешение
java.безопасность.Экземпляры разрешений означают запросы на авторизацию. Стандартные классы JDK создают их для всех потенциально опасных операций (таких как чтение/запись файла, открытие сокета и т. Д.) И передают их в SecurityManager Для надлежащей авторизации.
4.3. Конфигурация
Мы определяем разрешения в специальном формате политики. Эти разрешения принимают форму записей grant :
grant codeBase «file:$>/*» < permission java.security.AllPermission; >;
Приведенное выше правило codeBase является необязательным. Мы можем вообще не указывать там поля или использовать signedBy (интегрированный с соответствующими сертификатами в хранилище ключей) или principal ( java.security.Принципал присоединен к текущему потоку через javax.security.auth.Тема ). Мы можем использовать любую комбинацию этих правил .
По умолчанию JVM загружает файл общей политики системы, расположенный по адресу < java.home>/lib/security/java.policy . Если мы определили какую-либо локальную политику пользователя в /.java.policy , JVM добавляет ее в системную политику.
Также можно указать файл политики через командную строку: – Djava.security.policy=/my/policy-file . Таким образом, мы можем добавить политики к ранее загруженным системным и пользовательским политикам.
Существует специальный синтаксис для замены всех системных и пользовательских политик (если таковые имеются) – двойной знак равенства: – Djava.security.policy==/my/policy-file
5. Пример
Давайте определим пользовательское разрешение:
public class CustomPermission extends BasicPermission < public CustomPermission(String name) < super(name); >public CustomPermission(String name, String actions) < super(name, actions); >>
и общий сервис, который должен быть защищен:
public class Service < public static final String OPERATION = «my-operation»; public void operation() < SecurityManager securityManager = System.getSecurityManager(); if (securityManager != null) < securityManager.checkPermission(new CustomPermission(OPERATION)); >System.out.println(«Operation is executed»); > >
Если мы попытаемся запустить его с включенным менеджером безопасности, возникнет исключение:
java.security.AccessControlException: access denied («com.baeldung.security.manager.CustomPermission» «my-operation») at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472) at java.security.AccessController.checkPermission(AccessController.java:884) at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) at com.baeldung.security.manager.Service.operation(Service.java:10)
Мы можем создать ваш /.java.policy файл со следующим содержимым и попытаться повторно запустить приложение:
grant codeBase «file:» < permission com.baeldung.security.manager.CustomPermission «my-operation»; >;
Сейчас это работает просто отлично.
6. Заключение
В этой статье мы проверили, как организована встроенная система безопасности JDK и как мы можем ее расширить. Несмотря на то, что целевой вариант использования относительно редок, полезно знать об этом.
Как обычно, полный исходный код этой статьи доступен на GitHub .
Читайте ещё по теме:
- Введение в Derive4J
- Введение в Spring Security LDAP
- Основы контекста безопасности: Пользователь, Субъект и Принципал
- Spring Security OAuth2 – Простой отзыв токена (с использованием устаревшего стека Spring Security OAuth)
- Вступление к Jasypt
- Руководство по Java GSS API
- Введение в безопасность и веб-сайты
- Метки intro, overview, security, securitymanager
Источник: javascopes.com
Русские Блоги
- JCA (архитектура криптографии Java) — это архитектура Java, которая обеспечивает базовые структуры шифрования Java, такие как сертификаты, цифровые подписи, дайджесты сообщений, генераторы пар ключей и т. Д., Реализованные в пакете java.security.
- JCE (Java Cryptography Extension) — это расширение JCA, которое в основном отвечает за предоставление алгоритмов шифрования, таких как DES, AES, RSA и DSA. Поскольку алгоритмы шифрования будут продолжать улучшаться и будут рождаться новые алгоритмы, вся архитектура безопасности может быть расширена. Секс должен быть гарантирован.
- Пакет JCE ограничен экспортными ограничениями США из-за ограничений безопасности его алгоритма шифрования. Обычно мы используем «кастрационную версию», предоставляемую Oracle. Например, AES с 256-битным ключом по умолчанию не разрешен. Мы можем загрузить «полную версию» через официальный сайт Oracle. ,
Вот «полная версия зашифрованного пакета расширения»
http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html - Это выглядит после декомпрессии:
Согласно readme, поместите его в пакет / lib / security.
- JCE предоставляется не только Oracle. Существует несколько поставщиков, которые могут предоставлять пакеты расширений JCE. В файле java.security в каталоге установки jdk вы можете видеть, что поддерживаемые поставщики услуг являются Providers.
- Реализация JCA находится в пакете java.security. Этот пакет может реализовывать только алгоритм дайджеста сообщений. Другие полагаются на пакет расширений JCE и реализуются в пакете javax.crypto. Вы также можете добавить свой собственный поставщик и продолжить заполнение в соответствии с форматом, показанным на рисунке выше. 11-й в порядке. Используйте Security.addProvider («xxx») для завершения добавления Provider, используйте insertProviderAt («xxx», position) для завершения добавления в указанной позиции. Здесь используется понятие приоритета. Как показано на рисунке выше, чем меньше число, тем выше приоритет. Чем выше уровень.
- Чтобы заимствовать официальный пример Oracle, как показано в примере предыдущего примера, мы можем использовать следующий код для получения экземпляра дайджеста: например, если мы хотим получить экземпляр дайджеста, сгенерированного алгоритмом SHA-256, первое предложение кода перейдет к левому значению, пройдется по всем поставщикам, получим Поставщики, поддерживающие алгоритм, будут возвращены немедленно, ProviderB будет возвращен слева, а сгенерированная сводка содержит перегруженные методы. Вы можете указать Provider. Во второй строке кода указан ProviderC, затем ProviderC будет возвращен напрямую. Вы можете увидеть метод использования. Простой и гибкий.
md = MessageDigest.getInstance(«SHA-256»); md = MessageDigest.getInstance(«SHA-256», «ProviderC»);
- Чиновник не рекомендует использовать провайдеров, предоставляемых Sun, SunJSSE, SunJCE, SunRsaSign. Говорят, что по историческим причинам функции и надежность шифрования, предоставляемые этими поставщиками, не хороши.
- MessageDigest.getInstance («SHA-256»); каков поток выполнения этой строки кода? Мы нашли расположение MessageDigest в пакете и обнаружили, что существует другой класс SPI, похожий на его имя.Полное имя SPI — Service Provider Interface, который представляет собой сменное воплощение разработки программного обеспечения и часто используется при разработке подключаемых модулей.
- Такие классы, как MessageDigest, обычно называются классами «движка» и могут быть переведены как классы движка. Каждый такой класс движка имеет соответствующий класс SPI. Класс движка наследует класс SPI. Класс движка отвечает за то, что он вызывается пользователем, и вызывается класс движка. В классе SPI мы обнаружили, что все классы SPI являются абстрактными, то есть классы SPI предоставляют шаблоны, и другие провайдеры могут реализовывать методы в классе SPI. Они прозрачны для пользователей. Пользователям нужно только находиться в java. Конфигурация в безопасности достаточно, это подключаемый вариант, эти классы движков будут кратко представлены позже.
- Для некоторых поставщиков могут быть предоставлены псевдонимы алгоритмов шифрования. Официальный документ не рекомендует использовать псевдонимы, потому что другие поставщики могут не называть этот псевдоним.
- Если вы хотите узнать, каких провайдеров вы можете использовать, метод getProvider () Security может их получить. Есть много ключей, которые нужно получить. Я использую версию 1.8 с 600+ записями, как показано в следующем коде.
public static void main(String[] args) < for (Provider p : Security.getProviders()) < System.out.println(p); for (Map.Entry entry :p.entrySet()) < System.out.println(«t»+entry.getKey()); >> >
Во-вторых, библиотека классов пакета java.security.
- Такие классы, как MessageDigest, обычно называют классами движка. Классы движка в java. Пакет — это все унаследованные ими службы класса SPI. Этот подключаемый механизм облегчает общее расширение. Пакет java.security будет представлен ниже. Класс двигателя.
Класс MessageDigest
-
Вы можете использовать MessageDigest для генерации дайджеста указанного алгоритма шифрования. Код выглядит следующим образом. Сначала вы получаете экземпляр соответствующего алгоритма в соответствии со статическим методом MessageDigest, затем вызываете метод update () для обновления дайджеста и, наконец, используете метод digest () для генерации дайджеста.
MessageDigest digest = MessageDigest.getInstance(«SHA»); digest.update(input); byte[] output = digest.digest();
2. Основной интерфейс
- Ключ — это интерфейс, абстрактное понятие секретного ключа. Все классы, связанные с секретными ключами, должны реализовывать этот интерфейс. Посмотрев исходный код, мы обнаружим, что этот интерфейс наследует интерфейс Serializable. Это происходит потому, что секретный ключ в основном находится в системе. Этот интерфейс очень прост и имеет только три метода: public String getAlgorithm (); // Получить имя алгоритма
public String getFormat (); // Получить формат кодирования формата ключа
public byte [] getEncoded (); // Возвращаем ключ в двоичном формате - Его наследуют три интерфейса: SecretKey, PublicKey и PrivateKey. SecretKey является абстракцией симметричного ключа. Секретный ключ алгоритма симметричного шифрования предоставляется SecretKey. PublicKey и PrivateKey соответствуют открытому и секретному ключам в алгоритме асимметричного шифрования.
Интерфейс 3.KeyPair
- KeyPair является абстракцией пары ключей алгоритма асимметричного шифрования. Как показано на рисунке ниже, конструктор этого класса имеет только два параметра, типы PublicKey и PrivateKey. Этот класс не предоставляет методы установки открытого и закрытого ключей. Способ создания метода — это создание пары ключей.
4.KeyPairGenerator класс
-
Генерация пары ключей завершается с помощью KeyPairGenerator. Это класс механизма, который также наследует класс SPI. Для завершения создания пары ключей используется фабричный метод getInstance (). Экземпляр получается путем вызова метода getInstance () keyPairGenerator. , Инициализируйте длину ключа, а затем получите пару ключей.
KeyPairGenerator generator = KeyPairGenerator.getInstance(«DSA»); generator.initialize(1024); KeyPair keys = generator.generateKeyPair();
5. Класс KeyFactory
-
Основной функцией KeyFactory является генерация секретного ключа в соответствии с указанной спецификацией. Например, в следующем коде используется спецификация PKCS8. Существует много таких спецификаций, как показано на следующем рисунке:
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(«RSA»); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
6. Подпись класс
-
Класс Signature в основном используется для генерации и проверки цифровых подписей. Этап генерации цифровых подписей обычно называется «подписанием». Шаг проверки цифровых подписей обычно называется «проверкой подписи». Во-первых, мы используем заводской метод KeyPairGenerator getInstance ().
Получите экземпляр пары ключей экземпляра, инициализируйте длину ключа 1024, сгенерируйте пару ключей, создайте экземпляр подписи подписи в соответствии с указанным алгоритмом, инициализируйте его на основе закрытого ключа и вызовите метод sign () для завершения подписания. Следующий код показывает процесс подписания. :
byte[] data = «Signature Data».getBytes(); KeyPairGenerator generator = KeyPairGenerator.getInstance(«DSA»); generator.initialize(1024); KeyPair keyPair = generator.generateKeyPair(); Signature signature = Signature.getInstance(generator.getAlgorithm()); signature.initSign(keyPair.getPrivate()); signature.update(data); byte[] signData = signature.sign();
signature.initVerify(keyPair.getPublic()); signature.update(data); boolean status = signature.verify(signData);
7. Класс KeyStore
-
KeyStore — это абстракция хранилища ключей, которое используется для управления ключами и сертификатами. Это также класс ядра. В следующем коде мы загружаем хранилище ключей из локального с помощью пароля для загрузки хранилища ключей. Здесь мы можем видеть через keyStore.aliases () ; Полный список псевдонимов получен, поскольку хранилище ключей загружает секретный ключ через псевдоним, принцип аналогичен вышеупомянутому поставщику, и возвращается первый псевдоним.
String keyPassword = «123456»; inputStream = new FileInputStream(new File(keyPath)); KeyStore keyStore = KeyStore.getInstance(keyType); keyStore.load(inputStream, keyPassword.toCharArray()); Enumeration enum2 = keyStore.aliases(); String keyAlias = null; if (enum2 == null) < return null; >else < if (enum2.hasMoreElements()) < keyAlias = (String) enum2.nextElement(); >else < return null; >> PrivateKey priviteKey = keyStore.getKey(keyAlias, keyPassword.toCharArray());
Источник: russianblogs.com
Application Blocked by Java Security
Что делать, если вы столкнулись с ошибкой Java, которая сопровождается сообщением Application Blocked by Java Security?
Application Blocked by Java Security как исправить
Ошибку Application Blocked by Java Security исправить можно следующим образом:
Откройте Панель управления Java. Пуск → Все программы → Java → Configure Java.
Во вкладке Security найдите пункт Edit Site List.
В появившемся окне необходимо добавить адрес в список исключений, для чего нажмите Add.
Впишите адрес сайта и нажмите Ок.
В открывшемся окне предупреждения нажмите Continue.
Все. Адрес добавлен в список исключений Java. Однако при следующем запросе придется нажимать некоторую кнопку Run.
Перезапустите браузер и проверьте работоспособность.
Источник: winternete.ru