箱,
我即将使用Spring 3 MVC作为Web框架开发Web应用程序,Hibernate Annotations作为ORM框架但是,我面临着为此应用程序设计基于数据库的良好访问控制的问题。在我的工作中,我们习惯于这样设计:
(CompanyName)User.java - 表示系统中用户的类
Profile.java - 与(公司名称) NN 关系中系统中 ROLE 的类)用户即可。使用 ROLE ,我指的是一个用户组,例如(ADMIN,ANONYMOUS,CUSTOMER SERVICE USER等)
UserProfile.java - 表示用户与个人资料之间关系的类。它表示数据库中 N-N 关系的 JOIN TABLE 。
Module.java - 在Web应用程序中表示 MODULE 的类。每个模块都由无限功能组成,但每个功能只能与一个 MODULE 相关联。例如, USER AUTHENTICATION 功能与安全或 AUTHENTICATION 模块相关。模块是使用@Controller标记的应用程序中的控制器。
Feature.java - 在应用程序中表示 FEATURE 的类。每个功能都由一个或多个操作组成。例如,用户管理是一个功能。因此,它由许多操作组成(例如CREATE,READ,UPDATE和DELETE USER)。此外,FEATURE有一个ENTRY URL,表示该功能的URL(用于在单击按钮/链接时将用户重定向到该功能)。每个URL都映射到模块(控制器)中的方法。
Operation.java - 表示Web应用程序中 OPERATION 的类。操作基本上是单个/基本操作,例如 REGISTER USER 或 REMOVE USER ,但不一定是CRUD操作。每个操作都有一个 ENTRY URL (显示开始操作的页面的URL)。例如,对于 USER REGISTRATION 操作,条目 URL 将为 / webapplicationName / moduleName(USER)/ featureName(USER MANAGEMENT)/ operationName(REGISTER USER) 即可。但是操作可能需要页面流才能完成。例如, USER REGISTRATION 操作可能需要一个包含注册表单的页面,一个URL(通常映射到一个方法)作为提交表单的操作和一个 SUCCESS / ERROR 页面,显示 SUCCESS / ERROR 消息。
Permission.java - 表示系统中 URL 的类。每个权限与1个或多个操作(Operation.java)相关,以组成 PAGE FLOW 。例如: USER REGISTRATION 操作可能包含以下网址/权限:
/ webapplicationName / moduleName(USER)/ featureName(USER MANAGEMENT)/ operationName(USER REGISTRATION)/ register - 映射到(CompanyNameUser)控制器中的方法的URL以提交表单(表单操作)并保存在通常调用(CompanyNameUser)DAO的数据库中
/ webapplicationName / moduleName(USER)/ featureName(USER MANAGEMENT)/ operationName(REGISTER USER)/ success / - 映射到Controller中的方法以显示SUCCESS MESSAGE的URL
/ webapplicationName / moduleName(USER)/ featureName(USER MANAGEMENT)/ operationName(REGISTER USER)/ error / - 映射到Controller中的方法以显示错误消息的URL
ProfilePermission.java - 表示配置文件和权限之间的N-N关系的JOIN TABLE的类。
这里的问题是,如果我使用Spring Security实现访问控制,我注定要实现一个User.java类(我不能自定义名称),我也需要一个ROLES类和其他用于AUTHORITIES的类。所以,我无法建立自己的访问控制流程。我想过使用SERVLET FILTER来检查权限接受/拒绝访问。但是,当我尝试重定向到URL或只是在我的过滤器中执行chain.doFilter()时,它只显示ERROR 404.我认为这是因为我使用 DefaultAnnotationHandlerMapping 处理请求。也就是说,我的配置如下:
的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_2_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>
根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>
servlet的上下文
<?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实现我自己的自定义进程?我应该在处理程序映射中使用拦截器而不是使用过滤器吗?我将不胜感激任何帮助/建议。
提前致谢!
答案 0 :(得分:2)
看看Apache Shiro。它可能更适合您的要求。
答案 1 :(得分:0)
这是一个非常晚的回应,但这是为了后代。
我同意sourcedelica Apache Shiro是个好看的地方。但是,另外,我建议你退一步看看问题背后的理论。基本上,您要实现的是基于角色的访问控制模型,其中包含用户,组,角色和权限。此外,通过阅读您的问题,听起来您在请求访问的用户和目标资源之间存在关系。
考虑到这一点,您需要的是ABAC - 基于属性的访问控制 - 正如NIST在2014年早些时候发布的报告中所定义的那样。您可以read the report here。
使用ABAC,您可以根据属性描述您的用户 - 任何属性 - 例如角色,位置,年龄,公民身份......同样,您可以通过这种方式描述资源和对象以及尝试的操作和上下文。< / p>
这意味着使用属性和ABAC,您可以轻松实现以下授权要求:
要实施ABAC,请继续使用XACML。 XACML是OASIS定义的可扩展访问控制标记语言。它为您提供:
谷歌周围。 Java有很多XACML资源。
使用ABAC和XACML的好处是,您最终会将访问控制与业务逻辑分离,这意味着您可以独立于授权逻辑更改应用程序,反之亦然。
HTH