Здесь вы можете найти рабочий проект https://github.com/angeloimm/springbasicauth
Я знаю, что в файле pom.xml много бесполезных зависимостей, но я начал с уже существующего проекта, и у меня не было времени его удалить
В основном вы должны:
- настройка безопасности пружины
- Настроить пружину MVC
- реализует ваш собственный провайдер аутентификации в соответствии с Spring Security. Обратите внимание, что я использовал inMemoryAuthentication. Пожалуйста, измените его в соответствии с вашими пожеланиями
Позвольте мне объяснить код.
Конфигурация Spring MVC :
@Configuration
@EnableWebMvc
@ComponentScan(basePackages= {"it.olegna.test.basic"})
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(final List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2HttpMessageConverter());
}
}
Здесь мы не делаем ничего другого, кроме настройки Spring MVC, сообщая ему, где найти контроллеры и т. Д., И используем конвертер одного сообщения; MappingJackson2HttpMessageConverter
для получения ответов JSON
Spring Security Configuration :
@Configuration
@EnableWebSecurity
@Import(value= {WebMvcConfig.class})
public class WebSecConfig extends WebSecurityConfigurerAdapter {
@Autowired private RestAuthEntryPoint authenticationEntryPoint;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("test")
.password(passwordEncoder().encode("testpwd"))
.authorities("ROLE_USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/securityNone")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
Здесь мы настраиваем Spring Security для использования базовой аутентификации HTTP для всех запросов, кроме тех, которые начинаются с securityNone. Мы используем NoOpPasswordEncoder
для кодирования предоставленного пароля; этот PasswrodEncoder абсолютно ничего не делает ... он оставляет passwrod без изменений.
RestEntryPoint
@Component
public class RestAuthEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
Эта точка входа отключает все запросы, не связанные с Аутентификация заголовок
SimpleDto : очень простой DTO, представляющий JSON-ответ от контроллера
public class SimpleDto implements Serializable {
private static final long serialVersionUID = 1616554176392794288L;
private String simpleDtoName;
public SimpleDto() {
super();
}
public SimpleDto(String simpleDtoName) {
super();
this.simpleDtoName = simpleDtoName;
}
public String getSimpleDtoName() {
return simpleDtoName;
}
public void setSimpleDtoName(String simpleDtoName) {
this.simpleDtoName = simpleDtoName;
}
}
TestBasicController : очень простой контроллер
@RestController
@RequestMapping(value= {"/rest"})
public class TestBasicController {
@RequestMapping(value= {"/simple"}, method= {RequestMethod.GET}, produces= {MediaType.APPLICATION_JSON_UTF8_VALUE})
public ResponseEntity<List<SimpleDto>> getSimpleAnswer()
{
List<SimpleDto> payload = new ArrayList<>();
for(int i= 0; i < 5; i++)
{
payload.add(new SimpleDto(UUID.randomUUID().toString()));
}
return ResponseEntity.ok().body(payload);
}
}
Так что если вы попробуете этот проект с помощью почтальона или любого другого тестера, у вас может быть 2 сценария:
- требуется аутентификация
- все ок
Предположим, вы хотите вызвать URL http://localhost:8080/test_basic/rest/simple без передачи заголовка аутентификации. Код статуса HTTP будет 401 Unauthorized
Это означает, что требуется заголовок аутентификации
Добавив этот заголовок к запросу Authorization Basic dGVzdDp0ZXN0cHdk
все работает довольно хорошо
Обратите внимание, что String dGVzdDp0ZXN0cHdk
- это кодировка Base64 строки username:password
; в нашем случае это кодировка Base64 test:testpwd
, определенная в inMemoryAuthentication
Надеюсь, это полезно
Angelo
ОБСЛУЖИВАНИЕ ДАННЫХ ПОЛЬЗОВАТЕЛЯ ВЕБ-БЕЗОПАСНОСТИ
Чтобы настроить Spring Security для получения сведений о пользователе из БД, вы должны сделать следующее:
создайте реализацию org.springframework.security.core.userdetails.UserDetailsService следующим образом:
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private BasicService svc;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
BasicUser result = svc.findByUsername(username);
if( result == null )
{
throw new UsernameNotFoundException("No user found with username "+username);
}
return result;
}
}
Вставьте его в конфигурацию безопасности Spring и используйте его так:
public class WebSecConfig extends WebSecurityConfigurerAdapter {
@Autowired private RestAuthEntryPoint authenticationEntryPoint;
@Autowired
UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// auth
// .inMemoryAuthentication()
// .withUser("test")
// .password(passwordEncoder().encode("testpwd"))
// .authorities("ROLE_USER");
auth.userDetailsService(userDetailsService);
auth.authenticationProvider(authenticationProvider());
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/securityNone")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
Я нажал код на предоставленной мной ссылке на github. Там вы можете найти полный рабочий пример, основанный на:
- пружина 5
- пружина безопасности 5
- спящий режим
- h2 DB
Не стесняйтесь адаптировать его к вашему собственному сценарию