Введение в безопасность 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…