Люди, которые работают в IT, часто путают аутентификацию и авторизацию. Раньше я сам тоже путал эти понятия и замечаю, что на некоторых проектах коллеги с опытом в индустрии сталкиваются с той же ситуацией. Это может быть не безопасно для ПО которое разрабатывается, поскольку неверное определение может привести к неправильным выводам и решениям.
Аутентификация (AuthN) – это способ подтвердить, что вы действительно тот, за кого себя выдаете. Это паспорт в цифровом мире: пароли, различная биометрия и другие экзотические способы – все это примеры аутентификации. Это как сказать: “Привет, это я!”
Авторизация (AuthZ) – это уже другой зверь. Это про то, что вы можете делать после того, как подтвердили свою личность. Представьте, что вы вошли в интернет-магазин. А вот теперь вопрос: можете ли вы просто просматривать товары, добавлять их в корзину или у вас есть доступ к админ-панели для изменения ассортимента? Это и есть авторизация – правила, которые определяют, какие действия вам доступны.
Зачем важно понимать разницу? Потому что, когда путаются эти понятия, возникают большие проблемы. Например, если вы путаете, кто может войти в систему (аутентификация) с тем, что этот пользователь может делать (авторизация), вы открываете двери для множества уязвимостей. Так что давайте раз и навсегда проясним: аутентификация и авторизация – это разные вещи, и понимать их разницу важно для обеспечения безопасности вашего ПО. Также очень классно разбирают данный вопрос в статье Authn vs. authz: How are they different? By Cloudflare!
Аутентификация (AuthN)
Прежде чем пользователи смогут взаимодействовать с вашим ПО, необходимо убедиться, что они являются теми, за кого себя выдают. Это и есть аутентификация (Authentication, AuthN). Примеры с паролем один из базовых, скажем так один из способов первого фактора.
Простой пример аутентификации на spring security который мало вероятно будет сейчас в Production! Но как пример для наглядного понимания имеет место быть, далее в статье буду применять простые снипеты и оставлять ссылки на более богатые варианты =)
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user").password("{noop}password").roles("USER") .and() .withUser("admin").password("{noop}admin").roles("ADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/home").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } }
Достаточно хороший подход расписан в этом варианте и еще более информативнее в данной репе.
Как вы знаете современные системы безопасности все чаще переходят к использованию двухфакторной аутентификации (2FA) для повышения уровня защиты. Однофакторная аутентификация, такая как использование только пароля, больше не считается достаточно надежной из-за множества уязвимостей, связанных с паролями (например, их кража или перебора).
2FA добавляет дополнительн��й уровень безопасности, требуя второй способ проверки личности пользователя. Обычно это второй фактор из другой категории, например:
Что-то, что вы знаете: Пароль или PIN-код.
Что-то, что у вас есть: Смартфон или токен.
Что-то, что вы являетесь: Биометрические данные, такие как отпечатки пальцев или распознавание лица.
Отправка СМС
public class TwoFactorAuthenticationService { // Метод для отправки SMS public void sendSmsCode(String phoneNumber) { String code = generateCode(); // Логика для отправки SMS SmsSender.send(phoneNumber, "Ваш код подтверждения: " + code); // Сохранение кода в базе данных или кэше saveCode(phoneNumber, code); } // Генерация случайного кода private String generateCode() { // Логика генерации кода return String.valueOf(new Random().nextInt(999999)); } // Сохранение кода private void saveCode(String phoneNumber, String code) { // Логика сохранения кода (например, в базе данных или кэше) CodeRepository.save(phoneNumber, code); } }
Проверка той самой СМС
@RestController @RequiredArgsConstructor public class TwoFactorAuthenticationController { private TwoFactorAuthenticationService twoFactorAuthService; // Метод для проверки кода @PostMapping("/verifyCode") public ResponseEntity<String> verifyCode(@RequestParam String phoneNumber, @RequestParam String code) { boolean isCodeValid = twoFactorAuthService.verifyCode(phoneNumber, code); if (isCodeValid) { return ResponseEntity.ok("Код подтвержден успешно"); } else { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Неверный код"); } } } @Service public class TwoFactorAuthenticationService { // Метод для проверки кода public boolean verifyCode(String phoneNumber, String code) { String savedCode = getCode(phoneNumber); return code.equals(savedCode); } // Получение кода из базы данных или кэша private String getCode(String phoneNumber) { // Логика получения кода return CodeRepository.findByPhoneNumber(phoneNumber); } }
Да да это все еще псевдокод, тут этот момент разбирается более наглядно.
Понятное дело что 2FA это не предел, не зря ведь есть термин MFA и тут уже все зависит от потребности бизнеса конкретному к вашему ПО.
Авторизация (AuthZ)
После того как пользователь прошел аутентификацию, следующей важной задачей является авторизация (Authorization, AuthZ). Авторизация определяет, что пользователь может делать в системе, к каким ресурсам у него есть доступ и какие действия он может выполнять. Представьте, что вы вошли в интернет-магазин. А вот теперь вопрос: можете ли вы просто просматривать товары, добавлять их в корзину или у вас есть доступ к админ-панели для изменения ассортимента? Это и есть авторизация – правила, которые определяют, какие действия вам доступны.
Role-Based Access Control (RBAC)
RBAC, или управление доступом на основе ролей, предоставляет доступ к ресурсам в зависимости от ролей (пользователь, модератор, администратор и так далее), назначенных пользователю. Это один из наиболее распространенных методов авторизации.
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .requestMatchers("/", "/home").permitAll() .requestMatchers("/user/**").hasRole("USER") .requestMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } }
Attribute-Based Access Control (ABAC)
ABAC, или управление доступом на основе атрибутов, предоставляет доступ на основе атрибутов пользователя, ресурсов и окружающей среды. Этот метод позволяет более гибко управлять доступом.
// Пример реализации ABAC может включать сложные правила на основе атрибутов, // таких как должность пользователя, время дня или местоположение. @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .requestMatchers("/", "/home").permitAll() .requestMatchers("/user/**").access("hasRole('USER') and hasIpAddress('192.168.1.0/24')") .requestMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } }
// Здесь мы указываем, что доступ к URL, начинающимся с "/user/**", // разрешен только пользователям с ролью "USER" и IP-адресом из подсети // "192.168.1.0/24". Это пример использования атрибутов для контроля доступа. @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .requestMatchers("/", "/home").permitAll() .requestMatchers("/user/**").access("hasRole('USER') and hasIpAddress('192.168.1.0/24')") .requestMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); }
Таким образом, современные системы безопасности могут использовать различные подходы к авторизации, чтобы обеспечить гибкость и защиту. Также более наглядный пример RBAC/ABAC можно найти в данном материале.
Вот что в итоге, Карл!
Аутентификация и авторизация – два различных процесса, которые играют ключевые роли в обеспечении безопасности ваших систем. Несмотря на то, что они часто упоминаются вместе, их цели и методы кардинально различаются.
Непонимание разницы между аутентификацией и авторизацией может привести к серьезным уязвимостям в системе безопасности. Например, сильная аутентификация без соответствующей авторизации может позволить злоумышленникам получить доступ к конфиденциальным данным или функциям, к которым они не должны иметь доступ. Аналогично, даже при правильной авторизации, недостаточная аутентификация может оставить систему открытой для атак. Понимание и правильное внедрение аутентификации и авторизации помогает защитить ваши системы и данные от несанкционированного доступа, минимизировать риски утечек информации и повысить общую безопасность. Эти процессы необходимы для создания надежных и защищенных приложений, где каждая составляющая выполняет свою важную роль.
Таким образом, разница между аутентификацией и авторизацией – это не просто теоретический вопрос, а важный аспект, который влияет на безопасность и эффективность ваших решений. Осознание и правильное использование этих процессов помогает создавать более защищенные системы, отвечающие современным требованиям безопасности.
