Spring Security Basic Authentication

Spring Security Basic Authentication

1. обзор

В этом руководстве показано, как установить, настроить и настроитьBasic Authentication with Spring. Мы собираемся построить на основе простогоSpring MVC example и защитить пользовательский интерфейс приложения MVC с помощью механизма Basic Auth, предоставляемого Spring Security.

2. Конфигурация безопасности Spring

Мы можем настроить Spring Security с помощью конфигурации Java:

@Configuration
@EnableWebSecurity
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyBasicAuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
          .withUser("user1").password(passwordEncoder().encode("user1Pass"))
          .authorities("ROLE_USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
          .antMatchers("/securityNone").permitAll()
          .anyRequest().authenticated()
          .and()
          .httpBasic()
          .authenticationEntryPoint(authenticationEntryPoint);

        http.addFilterAfter(new CustomFilter(),
          BasicAuthenticationFilter.class);
    }

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

Здесь мы используем элементhttpBasic() для определения базовой аутентификации внутри методаconfigure() класса, расширяющегоWebSecurityConfigurerAdapter.

То же самое можно достичь с помощью XML:



    
    



    
        
            
        
    

Здесь важен элемент<http-basic> внутри основного элемента конфигурации<http> - этого достаточно, чтобы включить базовую аутентификацию для всего приложения. Диспетчер аутентификации не является предметом данного руководства, поэтому мы используем диспетчер в памяти с пользователем и паролем, заданными в виде открытого текста.

web.xml веб-приложения, включающего Spring Security, уже обсуждалось вSpring Logout tutorial.

3. Использование защищенного приложения

Командаcurl - это наш незаменимый инструмент для работы с защищенным приложением.

Во-первых, давайте попробуем запросить/homepage.html без предоставления каких-либо учетных данных:

curl -i http://localhost:8080/spring-security-rest-basic-auth/api/foos/1

Возвращаем ожидаемые401 Unauthorized иthe Authentication Challenge:

HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=E5A8D3C16B65A0A007CFAACAEEE6916B; Path=/spring-security-mvc-basic-auth/; HttpOnly
WWW-Authenticate: Basic realm="Spring Security Application"
Content-Type: text/html;charset=utf-8
Content-Length: 1061
Date: Wed, 29 May 2013 15:14:08 GMT

Браузер интерпретирует эту проблему и запрашивает учетные данные в простом диалоговом окне, но поскольку мы используемcurl, это не так.

Теперь давайте запросим тот же ресурс - домашнюю страницу - ноprovide the credentials, чтобы получить к ней доступ:

curl -i --user user1:user1Pass
  http://localhost:8080/spring-security-rest-basic-auth/api/foos/1

Теперь ответ сервера -200 OK вместе сCookie:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=301225C7AE7C74B0892887389996785D; Path=/spring-security-mvc-basic-auth/; HttpOnly
Content-Type: text/html;charset=ISO-8859-1
Content-Language: en-US
Content-Length: 90
Date: Wed, 29 May 2013 15:19:38 GMT

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

4. Дальнейшая настройка - Точка входа

По умолчаниюBasicAuthenticationEntryPoint, предоставленный Spring Security, возвращает полную страницу для ответа401 Unauthorized обратно клиенту. Это HTML-представление ошибки хорошо отображается в браузере, но не подходит для других сценариев, таких как REST API, где предпочтительным может быть представление json.

Пространство имен достаточно гибко для этого нового требования - для решения этой проблемы - точка входа может быть переопределена:

Новая точка входа определяется как стандартный компонент:

@Component
public class MyBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {

    @Override
    public void commence(
      HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
      throws IOException, ServletException {
        response.addHeader("WWW-Authenticate", "Basic realm="" + getRealmName() + """);
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        PrintWriter writer = response.getWriter();
        writer.println("HTTP Status 401 - " + authEx.getMessage());
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        setRealmName("example");
        super.afterPropertiesSet();
    }
}

Записывая непосредственно в HTTP-ответ, мы теперь имеем полный контроль над форматом тела ответа.

5. Зависимости Maven

Зависимости Maven для Spring Security обсуждались ранее вSpring Security with Maven article - нам понадобятся какspring-security-web, так иspring-security-config, доступные во время выполнения.

6. Заключение

В этом примере мы защитили приложение MVC с помощью Spring Security и Basic Authentication. Мы обсудили конфигурацию XML и использовали приложение с помощью простых команд curl. Наконец, установил точный формат сообщения об ошибке - перешел со стандартной страницы ошибок HTML в пользовательский текстовый или JSON-формат.

Полную реализацию этого руководства можно найти вthe GitHub project - это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.

Когда проект выполняется локально, образец HTML-кода доступен по адресу: