Статьи

Десять вещей, которые вы можете сделать с помощью Spring Security

Один

Вы можете указать поставщика авторизации по вашему выбору в конфигурационном файле Spring XML. Это можно сделать, настроив authentication-manager как определено в схеме Spring http://www.springframework.org/schema/security/spring-security-3.1.xsd. Упрощенное определение элемента authentication-manager выглядит примерно так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
<xs:element name='authentication-manager'>
 <xs:complexType>
  <xs:choice minOccurs='0' maxOccurs='unbounded'>
   <xs:element name='authentication-provider'>
    <xs:complexType>
     <xs:choice minOccurs='0' maxOccurs='unbounded'>
      <xs:element ref='security:any-user-service'/>
      <xs:element name='password-encoder'>...</xs:element>
     </xs:choice>
     <xs:attributeGroup ref='security:ap.attlist'/>
    </xs:complexType>
   </xs:element>
   <!-- This is BIG -->
   <xs:element name='ldap-authentication-provider'>...</xs:element>
  </xs:choice>
  <xs:attributeGroup ref='security:authman.attlist'/>
 </xs:complexType>
</xs:element>

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

01
02
03
04
05
06
07
08
09
10
<authentication-manager alias='authenticationManager'>
  <authentication-provider>
   <user-service>
    <user authorities='ROLE_GUEST' name='guest' password=''/>
   </user-service>
  </authentication-provider>
  <authentication-provider>
   <jdbc-user-service data-source-ref='dataSource'/>
  </authentication-provider>
 </authentication-manager>

Два

Вы можете настроить правила авторизации в своем XML-файле Spring, связав URL-адреса с ролями пользователей с помощью элемента intercept-url . Элемент intercept-url является дочерним элементом элемента http , сокращенное определение которого выглядит следующим образом:

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
<xs:element name='http'>
 <xs:complexType>
  <xs:choice minOccurs='0' maxOccurs='unbounded'>
   <xs:element name='intercept-url'>
    <xs:complexType>
     <xs:attributeGroup ref='security:intercept-url.attlist'/>
    </xs:complexType>
   </xs:element>
   <!-- Details omitted for clarity -->
   <xs:element name='access-denied-handler'>...</xs:element>
   <xs:element name='form-login'>...</xs:element>
   <xs:element name='openid-login'>...</xs:element>
   <xs:element name='x509'>...</xs:element>
   <xs:element ref='security:jee'/>
   <xs:element name='http-basic'>...</xs:element>
   <xs:element name='logout'>...</xs:element>
   <xs:element name='session-management'>...</xs:element>
   <xs:element name='remember-me'>...</xs:element>
   <xs:element name='anonymous'>...</xs:element>
   <xs:element name='port-mappings'>...</xs:element>
   <xs:element ref='security:custom-filter'/>
   <xs:element ref='security:request-cache'/>
   <xs:element name='expression-handler'>...</xs:element>
  </xs:choice>
  <xs:attributeGroup ref='security:http.attlist'/>
 </xs:complexType>
</xs:element>

Пример использования:

1
2
3
4
5
6
<security:http>
 <security:intercept-url pattern='/admin/**' access='hasRole('ROLE_ADMIN')'/>
 <security:intercept-url pattern='/account/**' access='hasRole('ROLE_USER')' />
 <security:intercept-url pattern='/**' access='hasRole('ROLE_ANONYMOUS')' />
 <!-- other elements removed for clarity -->
</security:http>

Три

Вы можете кодировать и проверять пароли, используя несколько классов, которые реализуют интерфейс Spring org.springframework.security.authentication.encoding.PasswordEncoder . У этого есть только два метода: encodePassword и isPasswordValid . Его многочисленные реализации включают в себя:

  • BaseDigestPasswordEncoder
  • BasePasswordEncoder
  • LdapShaPasswordEncoder
  • Md4PasswordEncoder,
  • Md5PasswordEncoder
  • MessageDigestPasswordEncoder
  • MessageDigestPasswordEncoder
  • PlaintextPasswordEncoder
  • ShaPasswordEncoder

четыре

Вы можете ограничить доступ к элементам страницы, используя библиотеку тегов Spring Security. Чтобы использовать эту библиотеку, вы включаете в JSP следующее определение taglib:

1
<%@ taglib prefix='sec' uri='http://www.springframework.org/security/tags' %>

Taglib содержит три полезных тега:

  • Авторизоваться
  • аутентификация
  • accesscontrollist

Наиболее полезным представляется тег authorize , который, используя примеры из документации Spring , можно использовать двумя способами. Во-первых, вы можете авторизоваться по ролям:

1
2
3
4
<sec:authorize access='hasRole('supervisor')'>
This content will only be visible to users who have
the 'supervisor' authority in their list of <tt>GrantedAuthority</tt>s.
</sec:authorize>

… а во-вторых, вы можете авторизоваться по URL

1
2
3
<sec:authorize url='/admin'>
This content will only be visible to users who are authorized to send requests to the '/admin' URL.
</sec:authorize>

Указанный URL-адрес должен соответствовать тегу intercept-url описанному в пункте 2.

Пять

Вы можете выполнить авторизацию на уровне метода, используя собственные аннотации Spring

  • @PreAuthorize('spEL expression')
  • @PostAuthorize('spEL expression')
  • @Secure

где выражение spEL может быть чем угодно, но обычно это что-то вроде: hasRole('ROLE_USER') .

Чтобы включить @PreAuthorize(...) и @PostAuthorize(...) добавьте в файл конфигурации XML следующее:

1
<global-method-security pre-post-annotations='enabled' />

@PreAuthorize(...) используется, как показано в следующем примере:

1
2
3
4
<span class='java0'><br />
  </span><span class='java16'>@PreAuthorize</span><span class='java8'>(</span><span class='java5'>'hasRole('ROLE_ADMIN')'</span><span class='java8'>) <br />
  </span><span class='java4'>public </span><span class='java9'>void </span><span class='java10'>deleteUser</span><span class='java8'>(</span><span class='java10'>String username</span><span class='java8'>)</span><span class='java10'>;<br />
</span>

Чтобы включить @Secure добавьте следующее в ваш конфигурационный файл Spring:

1
<global-method-security pre-post-annotations='enabled' />

Шесть

Вы можете обеспечить безопасность на уровне методов, используя реализацию Spring JSR-250, добавив в свой конфигурационный файл Spring следующее:

1
<global-method-security jsr250-annotations=”enabled”/>

Аннотации безопасности JSR-250 являются подмножеством аннотаций JSR-250 и включают в себя:

  • @RolesAllowed({“ROLE_USER”,”ROLE_ADMIN”})
  • @PermitAll
  • @DenyAll

При использовании аннотация JSR-250 выглядит примерно так:

1
2
@RolesAllowed({"ROLE_ADMIN","ROLE_USER"})
public void deleteUser(String username);

Семь

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

1
2
3
4
5
<form action='j_spring-openid-security-check' method='post'>
 <label for='openid_idenifier'>Login</label>:
 <input id='openid_identifier' name='openid_identifier' type='text'/>
 <input type='submit' value='Login' />
</form>

Следующим шагом является добавление элемента openid-login в http :

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
28
29
30
<xs:element name='http'>
 <xs:complexType>
  <xs:choice minOccurs='0' maxOccurs='unbounded'>
   <xs:element name='openid-login'>
    <xs:annotation>
     <xs:documentation>
      Sets up form login for authentication with an
      Open ID identity
     </xs:documentation>
    </xs:annotation>
    <xs:complexType>
     <xs:sequence>
      <xs:element minOccurs='0' maxOccurs='unbounded'
       ref='security:attribute-exchange' />
     </xs:sequence>
     <xs:attributeGroup ref='security:form-login.attlist' />
     <xs:attribute name='user-service-ref' type='xs:token'>
      <xs:annotation>
       <xs:documentation>
        A reference to a user-service (or
        UserDetailsService bean) Id
       </xs:documentation>
      </xs:annotation>
     </xs:attribute>
    </xs:complexType>
   </xs:element>
   <!-- Other elements omitted for clarity -->
  </xs:choice>
 </xs:complexType>
</xs:element>

Поскольку все дочерние элементы openid-login являются необязательными, самый простой способ включить OpenID — написать:

1
2
3
4
<http auto-config='true'>
 <openid-login/>
 <!-- other tags and attributes omitted for clarity -->
</http>

Наконец, вам нужно добавить spring-security-openid.jar в ваш проект.

8

Вы можете настроить свое приложение для аутентификации пользователей на встроенном LDAP-сервере (Lightweight Directory Access Protocol) с использованием XML-конфигурации. Это описано в сокращенной схеме XML, показанной ниже:

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
28
29
30
31
32
<xs:element name='ldap-server'>
 <xs:complexType>
  <xs:attributeGroup ref='security:ldap-server.attlist' />
 </xs:complexType>
</xs:element>
<xs:attributeGroup name='ldap-server.attlist'>
 <xs:attribute name='id' type='xs:token'>
  <xs:annotation>
   <xs:documentation>
    A bean identifier, used for referring to the bean elsewhere in the context.
   </xs:documentation>
  </xs:annotation>
 </xs:attribute>
 <xs:attribute name='port' type='xs:positiveInteger'/>
 <xs:attribute name='ldif' type='xs:string'>
  <xs:annotation>
   <xs:documentation>
    Explicitly specifies an ldif file resource to load
    into an embedded LDAP
    server. The default is classpath*:*.ldiff
   </xs:documentation>
  </xs:annotation>
 </xs:attribute>
 <xs:attribute name='root' type='xs:string'>
  <xs:annotation>
   <xs:documentation>
    Optional root suffix for the embedded LDAP server. Default is
    'dc=springframework,dc=org'
   </xs:documentation>
  </xs:annotation>
 </xs:attribute>
</xs:attributeGroup>

Файл LDIF , где LDIF обозначает формат обмена LDAP, представляет собой простой текстовый формат, используемый для описания набора записей LDAP.

Пример использования элемента ldap-server :

1
<ldap-server ldif='classpath:my-ldif-file.ldif' id='localserver' />

Чтобы использовать интеграцию Spring Security LDAP, не забудьте включить jar spring-security-ldap.jar в spring-security-ldap.jar вашего проекта.

9

Вы можете настроить свое приложение для аутентификации пользователей на удаленном сервере LDAP (Lightweight Directory Access Protocol), используя XML config. Это описано в сокращенной схеме XML, показанной ниже:

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
28
29
30
31
32
33
34
<xs:element name='ldap-server'>
 <xs:complexType>
  <xs:attributeGroup ref='security:ldap-server.attlist' />
 </xs:complexType>
</xs:element>
<xs:attributeGroup name='ldap-server.attlist'>
 <xs:attribute name='id' type='xs:token'>
  <xs:annotation>
   <xs:documentation>
    A bean identifier, used for referring to the bean elsewhere
    in the context.
   </xs:documentation>
  </xs:annotation>
 </xs:attribute>
 <xs:attribute name='url' type='xs:token'/>
 <xs:attribute name='port' type='xs:positiveInteger'/>
 <xs:attribute name='manager-dn' type='xs:string'>
  <xs:annotation>
   <xs:documentation>
    Username (DN) of the 'manager' user identity which will be used to
    authenticate to a (non-embedded) LDAP server. If omitted, anonymous
    access will be used.
   </xs:documentation>
  </xs:annotation>
 </xs:attribute>
 <xs:attribute name='manager-password' type='xs:string'>
  <xs:annotation>
   <xs:documentation>
    The password for the manager DN. This is required
    if the manager-dn is specified.
   </xs:documentation>
  </xs:annotation>
 </xs:attribute>
</xs:attributeGroup>

В документации говорится, что элемент ldap-server «Определяет расположение сервера LDAP или запускает встроенный сервер. URL указывает местоположение удаленного сервера. Если URL не указан, будет запущен встроенный сервер с прослушиванием предоставленного номера порта. Порт является необязательным и по умолчанию равен 33389. Bean-компонент Spring LDAP ContextSource будет зарегистрирован для сервера с предоставленным идентификатором ».

Это пример действительно минимальной конфигурации:

1
2
<ldap-server url='ldap://myServer/dc=captaindebug,dc=com:389' id='ldapExternal'
  manager-dn='uid=admin,ou=users,ou=systems' manager-password='s3cret'/>

После настройки сервера вам также необходимо настроить провайдера аутентификации LDAP. Кажется, есть несколько способов сделать это, и это не так просто, так что об этом позже, возможно …

10

Вы можете добавить
requires-channel='https' атрибут элемента <intercept-url /> вашего Spring Security Config, чтобы заставить любой соответствующий URL-адрес использовать HTTPS. Например, если вы хотите убедиться, что пароль всегда был зашифрован перед отправкой, вы можете добавить этот сокращенный XML в вашу конфигурацию:

1
2
3
4
<http auto-config='true' use-expressions='true'>
    <intercept-url pattern='/login' requires-channel='https'/>
    <!-- Other attributes and elements omitted -->   
</https>

Здесь есть еще пара вещей, но об этом позже …

Возможно, вы заметили, что я использовал файл XML-схемы Spring Security ( http://www.springframework.org/schema/security/spring-security-3.1.xsd ), чтобы объяснить некоторые функции в моем списке вещей, которые вы можно сделать с помощью Spring Security. Это потому, что я всегда рассматриваю Spring XSD как окончательный ориентир для всех вещей Spring. В ноябре 2011 года я написал блог на аннотацию @PostConstruct JSR-250 Spring, в котором содержалась ошибка (да, это правда, так и есть), на которую совершенно справедливо указал Крис Бимс из Spring, @CBeams, оставивший комментарий к JavaLobby. Версия этого блога. Я решил проверить схемы и обнаружил, что мы оба были неправы (хотя я был намного более неправ, чем Крис) — статья « Отладка капитана» теперь, насколько я могу судить, является правильной.

Безопасность приложений — довольно сложная тема, и если вы будете углубленно изучать ее, я предлагаю вам получить копию Spring Security 3 от Peter Mularien — ее также рекомендуют ребята из Spring.

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

Ссылка: десять вещей, которые вы можете сделать с помощью Spring Security от нашего партнера по JCG Роджера Хьюза в блоге Captain Debug’s Blog .