«Быстрое обучение Springboot» интегрирует Spring Security для реализации функции аутентификации.

Spring Boot

Введение в безопасность Spring

Spring Security является членом семейства Spring, которое обрабатывает проблемы с идентификацией и разрешениями. Spring Security может настраивать соответствующие идентификаторы ролей и разрешения идентификаторов в соответствии с потребностями пользователей, выполнять операции черного списка, перехватывать несанкционированные операции и т. д.

В этой статье объясняется использование Spring Security в Springboot.

импортировать зависимости

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Из-за автоматической настройки SpringBoot, после введения зависимостей Spring Security, он был настроен для нас по умолчанию. Если вы мне не верите, теперь посетите корневой каталог приложения:

Перешли на лендинг, ничего не писали. Мы удаляем зависимость от Spring Security, перезапускаем приложение, а затем снова обращаемся к корневому каталогу:

На этот раз вышла знакомая страница. На самом деле в этом и прелесть Springboot — автоматическая настройка. Мы только что представили зависимости Spring Security, и он был автоматически настроен для нас.

Пароль учетной записи по умолчанию

Мы можем просмотреть его через исходный код SecurityProperties, учетная запись по умолчанию — user, а пароль генерируется случайным образом при запуске, который можно найти в журнале:

Изменить пароль учетной записи по умолчанию

Мы можем изменить пароль учетной записи Spring Security по умолчанию через файл конфигурации следующим образом:

spring.security.user.name=happyjava
spring.security.user.password=123456

Версия springboot1.x:

security.user.name=admin
security.user.password=admin

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

Используйте Spring Security для настройки модуля аутентификации

Хотя для нас по умолчанию реализован простой модуль аутентификации при входе в систему, в реальной разработке этого все еще далеко не достаточно. Например, у нас есть несколько пользователей, несколько ролей и т. д. Все еще нужно разрабатывать вручную. Вот шаг за шагом, чтобы использовать Spring Security:

Настройте путь, который не требует входа в систему

Конечно, нам нужно настроить путь, по которому можно получить доступ без входа в систему, например: интерфейс входа в систему (иначе как вы входите).

Имеются следующие интерфейсы:

Создайте новый SecurityConfig, затем настройте перехватываемый путь и настройте белый список путей:

/**
 * @author Happy
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.antMatcher("/api/**")
                .authorizeRequests()
                .antMatchers("/api/notneedlogin/**").permitAll()
                .anyRequest().authenticated();
    }


}

Пожалуйста, смотрите версию с изображением, если макет грязный

С помощью метода antMatchers("url").permitAll() путь, настроенный с помощью /api/notneedlogin/**, будет освобожден Spring Security.

Запускаем проект под верификацией:

Интерфейс, который должен войти в систему, перехватывает и возвращает 403.

Путь, настроенный с помощью белого списка, успешно получил данные.

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

Откажитесь от конфигурации по умолчанию и настройте метод аутентификации.

Много раз нам нужно настроить метод аутентификации. Например, вместо использования сеанса для аутентификации я использую метод jwt без сохранения состояния (веб-токен json). В настоящее время нам нужно настроить Spring Security.

Во-первых, нам нужно создать реализацию UserDetails, которая является объектом разрешений пользователя, управляемым Spring Security:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class AdminUser implements UserDetails {

    private String username;

    @Override
    @SuppressWarnings("unchecked")
    public Collection<? extends GrantedAuthority> getAuthorities() {
        // 这里可以定制化权限列表
        return Collections.EMPTY_LIST;
    }

    @Override
    public String getPassword() {
        return null;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        // 这里设置账号是否已经过期
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        // 这里设置账号是否已经被锁定
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        // 这里设置凭证是否过期
        return true;
    }

    @Override
    public boolean isEnabled() {
        // 是否可用
        return true;
    }
}

Во-вторых, нам также нужен фильтр для перехвата запроса, чтобы определить, следует ли войти в систему и собрать UserDetails:

AuthFilter.class

@Component
public class AuthFilter extends OncePerRequestFilter {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String username = (String) request.getSession().getAttribute("username");
        if (username != null && !"".equals(username)) {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (userDetails != null && userDetails.isEnabled()) {
                UsernamePasswordAuthenticationToken authenticationToken =
                        new UsernamePasswordAuthenticationToken(userDetails,
                                null, userDetails.getAuthorities());
                // 把当前登陆用户放到上下文中
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(
                        request));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            } else {
                // 用户不合法,清除上下文
                SecurityContextHolder.clearContext();
            }
        }
        filterChain.doFilter(request, response);
    }

}

UserDetailsService в этом фильтре — это интерфейс Spring Security для загрузки UserDetails, код выглядит следующим образом:

У него есть только метод загрузки текущего привилегированного пользователя на основе имени пользователя, моя реализация выглядит следующим образом:

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // MOCK 模拟从数据库 根据用户名查询用户
        AdminUserEntity adminUser = new AdminUserEntity(1, "happyjava", "123456");
        // 构建 UserDetails 的实现类 => AdminUser
        return new AdminUser(adminUser.getUsername());
    }

}

MOCK здесь требует, чтобы пользователь фактически реализовал его, я просто демонстрирую его использование. Код AdminUserEntity выглядит следующим образом:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class AdminUserEntity {

    private Integer id;

    private String username;

    private String password;

}

На этом вся настройка Spring Security завершена.

контрольная работа

Следующие три интерфейса используются для проверки того, действует ли конфигурация:

Добавлен интерфейс входа для имитации реального входа пользователя. Среди них интерфейс needLogin использует аннотацию AuthenticationPrincipal для получения пользователя в контексте Spring Security (на самом деле это устанавливается в фильтре).

Если вы не вошли в систему, войдите в интерфейс test1:

Он был напрямую перехвачен, и интерфейс входа был вызван:

Посетите снова:

Интерфейс был успешно запрошен.

JWT-аутентификация без сохранения состояния

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

Сейчас для аутентификации используется популярный метод аутентификации с использованием зашифрованных токенов, и я также использую метод токена в проекте (jjwt). Основной метод заключается в том, что пользователь вызывает интерфейс входа в систему и возвращает строку зашифрованных строк, содержащих такую ​​информацию, как имя пользователя. Последующий запрос пользователя принесет токен и проверит, есть ли у пользователя разрешение, расшифровав его.

Суммировать

В этой статье объясняется использование Spring Security в качестве фреймворка аутентификации Spring Security довольно громоздок в настройке, но после завершения настройки действительно удобно получать контекстные пользовательские аннотации. Код выкладываю на GitHub, что всем удобно скачать и скопировать и использовать.Адрес такой:GitHub.com/happy Java00…