Содержание
Как уже упоминалось в предыдущей, эта статья будет посвящена использованию выражений 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 г. 5:30
|
Продолжение будет цикла? Очень класно написано. В частносте хотелось бы увидеть как выглядит вся эта конфигурация spring security без spring-security-config, т.е. на чистых бинах. Это нужно для того, чтоб понимать, что там происходит внутри. Я лично уже начал с этим разбираться, но пока не нашел лучшей доки чем исходники самого спринга...
|