Статьи

Как защитить службы REST в Джерси с помощью Spring Security и Basic аутентификации

В моем предыдущем сообщении в блоге « Быстрый способ проверить, работает ли REST API» — ПОЛУЧИТЕ подробности из файла манифеста , я показал, как разработать ресурс REST, чтобы легко проверить, достижим ли разработанный REST API. В этой статье я расскажу, как вы можете защитить этот ресурс с помощью Spring Security и Basic-аутентификации: «В контексте транзакции HTTP базовая аутентификация доступа — это метод для агента пользователя HTTP, который предоставляет имя пользователя и пароль при выполнении запроса. «.

Представленные здесь защищенные ресурсы REST являются частью более крупного проекта, который подробно представлен в Учебном пособии — разработка и реализация REST API на Java с использованием Jersey и Spring

Программное обеспечение используется

  1. Джерси JAX-RS реализация 2.14
  2. Весна 4.1.4
  3. Пружина безопасности 3.2.5
  4. Maven 3.1.1
  5. JDK 7

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

Библиотеки

Чтобы защитить службы REST с помощью базовой аутентификации, в пути к классам необходимы следующие библиотеки безопасности Spring. Поскольку я использую Maven, они перечислены как зависимости Maven в pom.xml:

Библиотеки безопасности Spring

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<!-- Spring security -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>${spring.security.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>${spring.security.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>${spring.security.version}</version>
</dependency>

Контекст приложения безопасности

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="UTF-8"?>
    xmlns:security="http://www.springframework.org/schema/security"   
    xsi:schemaLocation="
                 
     
    <!-- Stateless RESTful services use BASIC authentication -->
    <security:http create-session="stateless" pattern="/manifest/**">
        <security:intercept-url pattern="/**" access="ROLE_REST"/>
        <security:http-basic/>
    </security:http>
 
    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="rest" password="rest" authorities="ROLE_REST"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
 
</beans:beans>

Как видите, «отдыхающий» пользователь и роль определяются в памяти. Они определены в элементе <security:user-service> и его дочернем элементе <security:user> . Это гарантирует, что только пользователи с ролью ROLE_REST могут достичь:

менеджер аутентификации с настройкой памяти

1
2
3
4
5
6
7
<security:authentication-manager>
    <security:authentication-provider>
        <security:user-service>
            <security:user name="rest" password="rest" authorities="ROLE_REST"/>
        </security:user-service>
    </security:authentication-provider>
</security:authentication-manager>

Следующим шагом является защита URL-адресов /manifest/* , разрешающих доступ только вновь определенному остальному пользователю:

Защита URL-адресов с помощью доступа на основе ролей

1
2
3
4
<security:http create-session="stateless" pattern="/manifest/**">
    <security:intercept-url pattern="/**" access="ROLE_REST"/>
    <security:http-basic/>
</security:http>

Обычная HTTP-аутентификация включена в нашем приложении с помощью строки <security:http-basic/> .

Замечания:

Вы не можете определить ограничения безопасности Spring Security в файле applicationContext.xml, потому что они должны быть загружены с приемником сервлета и цепочкой фильтров. Они должны быть в правильном WebApplicationContext, определенном с помощью прослушивателя сервлета, а не связанного с сервлетом. Это связано с тем, что DelegatingFilterProxy будет искать контекст корневого приложения, определенный в ServletContext, который загружается ContextLoaderListener. Если вы определяете только applicationContext.xml, потому что фильтры загружаются первыми, перед сервлетами, фильтр не сможет найти контекст приложения, поэтому он не сможет правильно загрузиться.

web.xml

Теперь contextConfigLocation контекстный параметр contextConfigLocation , чтобы узнать о новом весеннем файле конфигурации security-context.xml :

web.xml — расширение контекста

1
2
3
4
5
6
7
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:spring/applicationContext.xml
        classpath:spring/security-context.xml
    </param-value>
</context-param>

Хук в Spring безопасности только для URL, связанных с манифестом :

Крюк в безопасности весны

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<servlet>
    <servlet-name>jersey-servlet</servlet-name>
    <servlet-class>
        org.glassfish.jersey.servlet.ServletContainer
    </servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>org.codingpedia.demo.rest.RestDemoJaxRsApplication</param-value>          
    </init-param>    
    <load-on-startup>1</load-on-startup>
</servlet>
 
<servlet-mapping>
    <servlet-name>jersey-servlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>
 
<!--Hook into spring security-->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
 
<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/manifest/*</url-pattern>
</filter-mapping>

Цепь фильтра безопасности Spring должна быть активирована.

тестирование

браузер

Если вы получаете доступ к защищенному местоположению через браузер, появляется стандартное всплывающее окно HTTP-аутентификации с запросом деталей аутентификации

стандартные всплывающие окна браузер

Поместите в rest / rest, и вы должны получить ответ JSON.

SoapUI

Довольно просто протестировать защищенный REST с помощью базовой аутентификации через soapUI. Смотрите следующее видео, чтобы узнать больше:

Запрос

Запросить ресурс с обычной аутентификацией

1
2
3
4
5
6
7
GET http://localhost:8888/demo-rest-jersey-spring/manifest HTTP/1.1
Accept-Encoding: gzip,deflate
Accept: application/json
Host: localhost:8888
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Authorization: Basic cmVzdDpyZXN0

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

  1. Имя пользователя и пароль объединяются в строку «имя пользователя: пароль»
  2. Результирующая строка затем кодируется с использованием варианта Base64 RFC2045-MIME, за исключением не ограниченного 76 символами / строкой
  3. Метод авторизации и пробел, то есть «Basic», затем ставятся перед закодированной строкой.

отклик

Ответ — подробности манифеста

01
02
03
04
05
06
07
08
09
10
11
12
HTTP/1.1 200 OK
Date: Tue, 03 Feb 2015 15:47:32 GMT
Content-Type: application/json
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, DELETE, PUT
Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Codingpedia
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 196
Server: Jetty(9.2.6.v20141205)
 
{"Implementation-Title":"DemoRestWS","Implementation-Version":"0.0.1-SNAPSHOT","Implementation-Vendor-Id":"org.codingpedia","Built-By":"Matei1.Adrian","Build-Jdk":"1.7.0_40","Manifest-Version":"1.0","Created-By":"Apache Maven 3.1.1","Specification-Title":"DemoRestWS","Specification-Version":"0.0.1-SNAPSHOT"}

Резюме

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

Примечание. Если вы решили использовать обычную аутентификацию для защиты ресурсов REST, убедитесь, что они вызываются по протоколу HTTPS. В настоящее время предпочтительным способом защиты ресурсов REST является использование OAuth . Подробнее об этом позже.