#spring #spring-mvc #spring-security
#spring #spring-mvc #spring-безопасность
Вопрос:
Я пытаюсь добавить безопасности в свое веб-приложение, используя Spring MVC, контроллеры REST и Spring Data. Проблема, с которой я сталкиваюсь, заключается в том, что методы, помеченные @PreAuthorized, доступны любому (вход в систему не требуется).
Мой контроллер:
@RestController
@RequestMapping("/controller")
public class Controller {
@RequestMapping(value = "/public/{name}", method = RequestMethod.GET)
public String storeEntityPublic(@PathVariable String name) {
String result = "Hello " name ", I am saving on the db. (PUBLIC)";
/* stuff */
return resu<
}
@PreAuthorize("hasAnyRole('ROLE_USER,ROLE_ADMIN')")
@RequestMapping(value = "/user/{name}", method = RequestMethod.GET)
public String storeEntityUserOrAdmin(@PathVariable String name) {
String result = "Hello " name
", I am saving on the db. (USER OR ADMIN)";
controller.saveEntity(name);
return resu<
}
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/admin/{name}", method = RequestMethod.GET)
public String storeEntityAdmin(@PathVariable String name) {
String result = "Hello Admin " name
", I am saving on the db. (ADMIN ONLY)";
controller.saveEntity(name);
return resu<
}
}
Моя конфигурация безопасности:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<global-method-security pre-post-annotations="enabled" />
<http auto-config="true" />
<!-- Configure Authentication mechanism -->
<authentication-manager alias="authenticationManager">
<authentication-provider>
<user-service>
<user name="admin" password="admin" authorities="ROLE_ADMIN" />
<user name="user" password="user" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Мой ApplicationContext правильно импортирует файл конфигурации безопасности.
В моем web.xml , Я добавил следующее:
<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>/*</url-pattern>
</filter-mapping>
Наконец, мой applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<context:property-placeholder location="classpath*:spring/*.properties" />
<context:component-scan base-package="org.my.project" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${database.driverClassName}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.username}" />
<property name="password" value="${database.password}" />
<property name="initialSize" value="3" />
<property name="maxActive" value="10" />
</bean>
<tx:annotation-driven mode="proxy"
transaction-manager="transactionManager" />
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit" />
<property name="dataSource" ref="dataSource" />
</bean>
<import resource="classpath:spring/applicationContext-jpa.xml" />
<import resource="classpath:spring/applicationContext-security.xml" />
</beans>
Проект правильно развернут, и у меня нет предупреждений относительно безопасности.
Комментарии:
1. Возможно, удалите файлы cookie в браузере и повторите попытку.
2. к сожалению, это не решение, я тестирую в режиме инкогнито.
3. Попробуйте добавить <intercept-url в spring-security-config.xml с помощью элемента <http.
4. Это работает, да, но мне нужно использовать режим на основе аннотаций.
5. Настроить перехват URL-адресов с использованием аннотаций? затем используйте @ Configuration в пользовательском классе config для настройки. Я предполагаю, что @ preauth отличается от конфигурации, @ PreAuth — это безопасность на уровне метода, то есть вы сужаете безопасность для каждого уровня.
Ответ №1:
В документации Spring Security говорится о аннотированных методах:
Аннотированные методы будут защищены только для экземпляров, которые определены как компоненты Spring (в том же контексте приложения, в котором включена защита метода).
Я полагаю, что вы определяете свои компоненты контроллера в другом контексте, чем вы определяете свой контекст безопасности. Попробуйте поместить приведенный ниже элемент в контекст, определяющий защищаемые компоненты.
<global-method-security pre-post-annotations="enabled" />
Комментарии:
1. Я не уверен, куда добавить этот элемент: у меня уже есть это в ApplicationContext-security xml. Я опубликовал также свой applicationContext.xml . Куда я должен добавить элемент global-method-security?
2. Попробуйте добавить его в свой applicationContext.xml .
3. Когда я добавляю его в applicationContext.xml и прокомментируйте перехваты, я могу свободно получить доступ ко всем страницам и методам, включая те, к которым не следует обращаться.
4. Странно, кажется, что все в порядке. Попробуйте добавить
<aop:config proxy-target-class="true" />
в applicationContext.xml поскольку ваши контроллеры не реализуют какой-либо интерфейс.