Друзья,
Я собираюсь разработать веб-приложение, используя Spring 3 MVC в качестве веб-фреймворка, аннотации Hibernate в качестве фреймворка ORM. Однако я столкнулся с проблемой разработки хорошего контроля доступа на основе базы данных для этого приложения. В моей работе мы привыкли проектировать так:
(CompanyName)User.java — класс, означающий Пользователя в системе.
Profile.java — класс, который означает РОЛЬ в системе в отношениях NN с (CompanyName)User. . Под РОЛИ я подразумеваю группу пользователей, такую как (АДМИН,АНОНИМНЫЙ,ПОЛЬЗОВАТЕЛЬ СЛУЖБЫ КЛИЕНТА и т. д.)
UserProfile.java — класс, означающий связь между Пользователем и Профилем. Он представляет собой JOIN TABLE для отношения N-N в базе данных.
Module.java — класс, означающий МОДУЛЬ в веб-приложении. Каждый модуль состоит из неограниченного количества функций, но каждая функция может быть связана только с одним МОДУЛЕМ. Например, функция АУТЕНТИФИКАЦИЯ ПОЛЬЗОВАТЕЛЯ будет связана с модулем БЕЗОПАСНОСТЬ или АУТЕНТИФИКАЦИЯ. Модули — это контроллеры в приложении, помеченные тегом @Controller.
Feature.java — класс, представляющий ФУНКЦИЮ в приложении. Каждая функция состоит из одной или нескольких операций. Например, УПРАВЛЕНИЕ ПОЛЬЗОВАТЕЛЯМИ — это ФУНКЦИЯ. Таким образом, он состоит из множества операций (например, СОЗДАНИЕ, ЧТЕНИЕ, ОБНОВЛЕНИЕ и УДАЛЕНИЕ ПОЛЬЗОВАТЕЛЯ). Кроме того, ФУНКЦИЯ имеет URL-адрес ВХОДА, который представляет собой URL-адрес этой функции (для перенаправления пользователя на эту функцию при нажатии кнопки/ссылки). Каждый URL-адрес сопоставляется с методом в модуле (контроллере).
Operation.java — класс, представляющий OPERATION в веб-приложении. Операция — это, по сути, одиночная/базовая операция, такая как РЕГИСТРАЦИЯ ПОЛЬЗОВАТЕЛЯ или УДАЛЕНИЕ ПОЛЬЗОВАТЕЛЯ, но не обязательно операция CRUD. У каждой операции есть URL-ВВОД (URL-адрес, показывающий страницу, с которой начинается операция). Например, для операции РЕГИСТРАЦИЯ ПОЛЬЗОВАТЕЛЯ запись URL будет иметь вид /webapplicationName/moduleName(USER)/featureName(USER MANAGEMENT)/operationName(REGISTER USER) . Но для операции может потребоваться поток страниц. Например, для операции РЕГИСТРАЦИЯ ПОЛЬЗОВАТЕЛЯ, вероятно, потребуется страница с регистрационной формой, URL-адрес (обычно сопоставленный с методом) в качестве действия для отправки формы и УСПЕХ/ОШИБКА. strong>, чтобы отобразить сообщение SUCCESS/ERROR.
Permission.java — класс, представляющий URL в системе. Каждое Разрешение связано с 1 или несколькими ОПЕРАЦИЯМИ (Operation.java) для создания ПОТОКА СТРАНИЦ. Например: операция РЕГИСТРАЦИЯ ПОЛЬЗОВАТЕЛЯ, вероятно, будет иметь следующие URL/РАЗРЕШЕНИЯ:
/webapplicationName/moduleName(USER)/featureName(USER MANAGEMENT)/operationName(USER REGISTRATION)/register — URL-адрес, сопоставленный с методом в (CompanyNameUser)Controller для отправки формы (действие формы) и для сохранения в базе данных, обычно вызывающей (CompanyNameUser)DAO
/webapplicationName/moduleName(USER)/featureName(USER MANAGEMENT)/operationName(REGISTER USER)/success/ — URL-адрес, сопоставленный с методом в контроллере для отображения СООБЩЕНИЯ ОБ УСПЕХЕ
/webapplicationName/moduleName(USER)/featureName(USER MANAGEMENT)/operationName(REGISTER USER)/error/ — URL-адрес, сопоставленный с методом в контроллере для отображения СООБЩЕНИЯ ОБ ОШИБКЕ
ProfilePermission.java — класс, представляющий JOIN TABLE для связи N-N между профилями и разрешениями.
Проблема здесь в том, что если я использую Spring Security для реализации контроля доступа, я обречен реализовать класс User.java (я не могу настроить имя), также мне понадобится класс для РОЛИ и другой для ПОЛНОМОЧИЙ. Итак, я не могу создать свой собственный поток управления доступом. Я подумал об использовании SERVLET FILTER для проверки разрешений на доступ/запрет доступа. Однако, когда я пытаюсь перенаправить на URL-адрес или просто выполнить chain.doFilter() внутри моего фильтра, он просто показывает ОШИБКУ 404. Я думаю, это потому, что я использую DefaultAnnotationHandlerMapping strong> для обработки запросов. Тем не менее, моя конфигурация выглядит следующим образом:
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.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.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="latin1"/>
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="pt"/>
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<ref bean="localeChangeInterceptor" />
</property>
</bean></beans>
5.xsd">`<display-name>cheapig</display-name>
<!-- ROOT CONTEXT DEFINITIONS -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>`
<listener>
<listener- class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- The filter to implement my access control -->
<filter>
<filter-name>securityFilter</filter-name>
<filter-class>org.cheapig.security.SecurityFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>securityFilter</filter-name>
<url-pattern>/**</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>cheapig</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet- class> <init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/cheapig/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cheapig</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping></web-app>
root-context.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.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.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="latin1"/>
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="pt"/>
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<ref bean="localeChangeInterceptor" />
</property>
</bean></beans>
контекст сервлета:
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Imports user-defined @Controller beans that process client requests -->
<beans:import resource="controllers.xml" />
<beans:import resource="hibernateMySQL5.xml"/>
<context:component-scan base-package="br.com.cheapig" />
</beans:beans>
SecurityFilter.java:
package br.com.cheapig.security;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class SecurityFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
И что я должен делать? Должен ли я использовать Spring Security? Есть ли способ реализовать мой собственный процесс с помощью Spring Security? Должен ли я использовать перехватчик в моем отображении обработчика вместо использования фильтра? Буду признателен за любую помощь/предложения.
Заранее спасибо!