Зміст
Як уже згадувалося в попередній, ця стаття буде присвячена використанню виразів Spring EL expressions в Spring Security. Будуть розглянуті всі можливі стандартні вирази.
Отже, приступимо... З попередньої статті стало зрозуміло, що для використання виразів в тезі http налаштувань безпеки необхідно додати атрибут use-expressions зі значенням true:
<http auto-config="true" use-expressions="true">
...
</http>
Кожний розглянутий вираз буде супроводжуватися прикладом для полегшення розуміння.
hasRole([role]) - повертає true якщо поточний користувач має зазначену роль:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/secure/**" access="hasRole('ROLE_USER')" />
</http>
hasAnyRole([role1,role2]) - повертає true якщо поточний користувач має будь-яку із зазначених ролей:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/hasanyrole/**" access="hasAnyRole('ROLE_ADMIN,ROLE_USER')" />
</http>
principal - дає прямий доступ до об'єкта користувача:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/principal/**" access="isAuthenticated() and principal.username == 'admin'" />
</http>
authentication - дає прямий доступ до об'єкта Authentication:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/authentication/**" access="authentication.name == 'admin'" />
</http>
permitAll - завжди повертає true (застосовується для публічного і статичного контенту):
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/public/**" access="permitAll" />
</http>
denyAll - завжди повертає false. Найбільш часто застосовується як завершальне правило, яке забороняє всі адреси, які не були описані правилами (вибір правила в Spring Security відбувається зверху вниз):
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/public/**" access="permitAll" />
<intercept-url pattern="/**" access="denyAll" />
</http>
isAnonymous() - повертає true якщо поточний користувач не авторизований:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/anonymousonly/**" access="isAnonymous()" />
</http>
У наведеному вище прикладі авторизований користувач не матиме доступу до вказаних адрес.
isRememberMe() - повертає true якщо користувач авторизований за допомогою можливості "Запам'ятати мене":
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/remembermeonly/**" access="isRememberMe()" />
</http>
isAuthenticated() - повертає true якщо користувач авторизований:
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/authenticatedonly/**" access="isAuthenticated()" />
</http>
isFullyAuthenticated() - повертає true якщо користувач авторизований без допомоги можливості "Запам'ятати мене":
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/fullyauthenticatedonly/**" access="isFullyAuthenticated()" />
</http>
Є ще один додатковий вираз hasIpAddress з класу WebSecurityExpressionRoot:
<http use-expressions="true">
<intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN') and hasIpAddress('192.168.1.0/24')"/>
</http>
Також в Spring Security є можливість створювати свої власні вирази.
Ви можете використовувати вирази не тільки в тезі http, а й у своїх методах. Для цього необхідно трохи відкоригувати конфігурацію веб-програми. Додайте в контексті сервлета (не в конфігурації безпеки!) наступний код:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
...
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="
...
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<sec:global-method-security pre-post-annotations="enabled" />
</beans:beans>
Повний servlet-context.xml виглядає наступним чином:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<annotation-driven />
<resources mapping="/resources/**" location="/resources/" />
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.seostella.springsecurityel" />
<sec:global-method-security pre-post-annotations="enabled" />
</beans:beans>
А в pom.xml ще одну залежність:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
Тепер Ви можете використовувати чотири анотації в методах своїх класів: @PreAuthorize, @PreFilter, @PostAuthorize і @PostFilter. Наприклад, так:
@PreAuthorize("hasRole('ROLE_GREETING')")
@ModelAttribute("greeting")
public String populateGreeting() {
return "Hi User!";
}
У разі якщо користувач не має ролі ROLE_GREETING, він побачить сторінку з помилкою 403.
Також є можливість додавання зрізів за допомогою protect-pointcut. Вам доведеться змінити тег global-method-security наприклад так:
<sec:global-method-security
pre-post-annotations="enabled">
<sec:protect-pointcut
expression="execution(* com.seostella.springsecurityel.controller.SecureController.*(..))"
access="ROLE_GREETING" />
</sec:global-method-security>
У файл pom.xml також потрібно додати залежність:
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.3</version>
</dependency>
Тепер всі методи класу SecureController будуть виконувати тільки якщо в користувача є роль ROLE_GREETING.
< | Logout в Spring Security |
25 жовтня 2012 р. 15:22
|
Класний сайт) чого ніде нема коментарів?)
|
27 травня 2013 р. 16:08
|
Отличный обзор. Спасибо.
|
3 вересня 2013 р. 23:40
|
Спасибо. Очень просто и доступно описано. Никаких лишних рассуждений.
|
20 жовтня 2013 р. 05:30
|
Продолжение будет цикла? Очень класно написано. В частносте хотелось бы увидеть как выглядит вся эта конфигурация spring security без spring-security-config, т.е. на чистых бинах. Это нужно для того, чтоб понимать, что там происходит внутри. Я лично уже начал с этим разбираться, но пока не нашел лучшей доки чем исходники самого спринга...
|