`

Spring Acegi鉴权管理之基础模式(BASIC)

    博客分类:
  • J2EE
阅读更多

Acegi久负盛名,这个家伙是一个spring中广泛使用的认证和安全工具,最初由spring社区爱好者发起,目的是为spring应用提供一个安全服务,比如用户认证及授权等。后来spring官方觉得这个东西很不错,就收编了,并且在2006年发布了spring官方的1.0版本。虽然是基于Acegi,但springsecurity已经在原有基础上增加了很多新的特性进来。为了能够方便一窥Acegi的真容,我们通过一个basic模式来看下Acegi是如何来处理用户认证及授权工作。

1、配置安全所需过滤器org.acegisecurity.util.FilterChainProxy,填充 filterInvocationDefinitionSource 属性如下所示:

<bean id ="filterChainProxy" class= "org.acegisecurity.util.FilterChainProxy">
    <property name ="filterInvocationDefinitionSource">
	 <value>
	     PATTERN_TYPE_APACHE_ANT
	     /**=basicProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
	 </value>
    </property>
</bean>

 注:默认情况下,在filterInvocationDefinitionSource属性中指明使用PATTERN_TYPE_APACHE_ANT,则说明,这里的配置信息是启用Apache Ant路径风格的URL匹配模式,FilterInvocationDefinitionSourceEditor会实例化PathBasedFilterInvocationDefinitionMap实例。如果这里没有指定则采用默认的正是表达式,此时RegExpBasedFilterInvocationDefinitionMap会被实例化。

FilterInvocationDefinitionSourceEditor在进行初始化过程中,acegi源码处理过程的片段代码如下:

if ((s == null) || "".equals(s)) {
    // Leave target object empty
    source.setDecorated(new RegExpBasedFilterInvocationDefinitionMap());
} else {
    // Check if we need to override the default definition map
    if (s.lastIndexOf(DIRECTIVE_PATTERN_TYPE_APACHE_ANT) != -1) {
        source.setDecorated(new PathBasedFilterInvocationDefinitionMap());

        if (logger.isDebugEnabled()) {
            logger.debug(("Detected " + DIRECTIVE_PATTERN_TYPE_APACHE_ANT
                + " directive; using Apache Ant style path expressions"));
        }
    } else {
        source.setDecorated(new RegExpBasedFilterInvocationDefinitionMap());
    }

    if (s.lastIndexOf(DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON) != -1) {
        if (logger.isDebugEnabled()) {
            logger.debug("Detected " + DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                + " directive; Instructing mapper to convert URLs to lowercase before comparison");
        }

        source.setConvertUrlToLowercaseBeforeComparison(true);
    }

 另外需要说明的是,PathBasedFilterInvocationDefinitionMap和RegExpBasedFilterInvocationDefinitionMap都是接口FilterInvocationDefinitionSource的实现类。

FilterInvocationDefinitionSourceEditor在初始化athBasedFilterInvocationDefinitionMap和RegExpBasedFilterInvocationDefinitionMap类时,提供了2个常量用:

  • DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON:FilterInvocationDefinitionSourceEditor类通过该常量的设值情况判断是否对当前路径进行小写转换
  • PATTERN_TYPE_APACHE_ANT:FilterInvocationDefinitionSourceEditor通过这个常量决定具体是采用正则模式还是ant路径风格模式。

我们这里根据执行顺序,指明了3个filter类过滤执行安全策略:basicProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor

basicProcessingFilter:在Basic模式下,用户名和密码通过对称加密算法,将用户的登录信息存放在http请求的header信息中。服务器在收到浏览器发送来的验证请求后,将加密过的用户名密码通过Apache提供的commons-codec工具包中的org.apache.commons.codec.binary.Base64进行解码。

例如:发起一次请求验证通过后的http头摘要如下:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:zh-CN,zh;q=0.8
Authorization:Basic dGVzdDox
Connection:keep-alive
Cookie:JSESSIONID=A749345B4E56805343189AA5A1223655
Host:localhost:8080
Referer:http://localhost:8080/rest-common-acegi/secure.jsp
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36

 

basicProcessingFilter片段代码如下:

String header = httpRequest.getHeader("Authorization");

if (logger.isDebugEnabled()) {
    logger.debug("Authorization header: " + header);
}

if ((header != null) && header.startsWith("Basic ")) {
    String base64Token = header.substring(6);
    String token = new String(Base64.decodeBase64(base64Token.getBytes()));

    String username = "";
    String password = "";
    int delim = token.indexOf(":");

    if (delim != -1) {
        username = token.substring(0, delim);
        password = token.substring(delim + 1);
    }

    if (authenticationIsRequired(username)) {
        UsernamePasswordAuthenticationToken authRequest =
                new UsernamePasswordAuthenticationToken(username, password);
        authRequest.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request));

        Authentication authResult;

        try {
            authResult = authenticationManager.authenticate(authRequest);
        } catch (AuthenticationException failed) {
            // Authentication failed
            if (logger.isDebugEnabled()) {
                logger.debug("Authentication request for user: " + username + " failed: " + failed.toString());
            }

            SecurityContextHolder.getContext().setAuthentication(null);

            if (rememberMeServices != null) {
                rememberMeServices.loginFail(httpRequest, httpResponse);
            }

            if (ignoreFailure) {
                chain.doFilter(request, response);
            } else {
                authenticationEntryPoint.commence(request, response, failed);
            }

            return;
        }

        // Authentication success
        if (logger.isDebugEnabled()) {
            logger.debug("Authentication success: " + authResult.toString());
        }

        SecurityContextHolder.getContext().setAuthentication(authResult);

        if (rememberMeServices != null) {
            rememberMeServices.loginSuccess(httpRequest, httpResponse, authResult);
        }
    }
}

chain.doFilter(request, response);
}

 

可以看出,basicProcessingFilter从Header中获取Authorization信息,并通过Apache的codec包中的解码工具对token进行解码,从而获取用户输入的用户名、密码信息,用于后面的校验动作。

basicProcessingFilter在获取到验证请求需要用到的用户名及密码信息后,实际的用户有效性验证,交给了org.acegisecurity.providers.ProviderManager来管理的org.acegisecurity.providers.dao.DaoAuthenticationProvider类的执行实际验证处理过程。
对basicProcessingFilter的详细配置如下:

<bean id ="basicProcessingFilter" class= "org.acegisecurity.ui.basicauth.BasicProcessingFilter">
    <property name ="authenticationManager" ref= "authenticationManager" />
    <property name ="authenticationEntryPoint" ref= "basicProcessingFilterEntryPoint" />
</bean>

<bean id ="basicProcessingFilterEntryPoint" class= "org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint">
    <property name ="realmName" value="Acegi First Realm Name" />
</bean>

<bean id ="authenticationManager" class= "org.acegisecurity.providers.ProviderManager">
    <property name ="providers">
         <list>
              <ref bean="daoAuthenticationProvider" />
         </list>
    </property>
</bean>

<bean id ="daoAuthenticationProvider" class= "org.acegisecurity.providers.dao.DaoAuthenticationProvider">
    <property name ="userDetailsService" ref= "inMemDaoImpl" />
</bean>
<bean id="inMemDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
    <property name="userMap">
        <value>
            test=111111,ROLE_SUPERVISOR
            zhangsan=111111,ROLE_SUPERVISOR,disabled
        </value>
    </property>
</bean>

 

接下来开始配置exceptionTranslationFilter,配置信息如下:

<!-- exception filter -->
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
    <property name="authenticationEntryPoint" ref="basicProcessingFilterEntryPoint" />
</bean>

 注:ExceptionTranslationFilter类用来处理权限验证失败时页面的路由情况,我们这里给ExceptionTranslationFilter配置了一个默认的basicProcessingFilterEntryPoint

对异常处理的片段代码如下:

public void commence(ServletRequest request, ServletResponse response, AuthenticationException authException)
    throws IOException, ServletException {
    HttpServletResponse httpResponse = (HttpServletResponse) response;
    httpResponse.addHeader("WWW-Authenticate", "Basic realm=\"" + realmName + "\"");
    httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
}

 从上面的代码可以看到,当权限验证失败后,response请求被指向了HttpServletResponse.SC_UNAUTHORIZED页面(“401”访问受限页面)

在HttpServletResponse中定义的返回取值范围及常量定义如下所示:

public static final int SC_CONTINUE = 100;
public static final int SC_SWITCHING_PROTOCOLS = 101;
public static final int SC_OK = 200;
public static final int SC_CREATED = 201;
public static final int SC_ACCEPTED = 202;
public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;
public static final int SC_NO_CONTENT = 204;
public static final int SC_RESET_CONTENT = 205;
public static final int SC_PARTIAL_CONTENT = 206;
public static final int SC_MULTIPLE_CHOICES = 300;
public static final int SC_MOVED_PERMANENTLY = 301;
public static final int SC_MOVED_TEMPORARILY = 302;
public static final int SC_FOUND = 302;
public static final int SC_SEE_OTHER = 303;
public static final int SC_NOT_MODIFIED = 304;
public static final int SC_USE_PROXY = 305;
public static final int SC_TEMPORARY_REDIRECT = 307;
public static final int SC_BAD_REQUEST = 400;
public static final int SC_UNAUTHORIZED = 401;
public static final int SC_PAYMENT_REQUIRED = 402;
public static final int SC_FORBIDDEN = 403;
public static final int SC_NOT_FOUND = 404;
public static final int SC_METHOD_NOT_ALLOWED = 405;
public static final int SC_NOT_ACCEPTABLE = 406;
public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
public static final int SC_REQUEST_TIMEOUT = 408;
public static final int SC_CONFLICT = 409;
public static final int SC_GONE = 410;
public static final int SC_LENGTH_REQUIRED = 411;
public static final int SC_PRECONDITION_FAILED = 412;
public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413;
public static final int SC_REQUEST_URI_TOO_LONG = 414;
public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
public static final int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
public static final int SC_EXPECTATION_FAILED = 417;
public static final int SC_INTERNAL_SERVER_ERROR = 500;
public static final int SC_NOT_IMPLEMENTED = 501;
public static final int SC_BAD_GATEWAY = 502;
public static final int SC_SERVICE_UNAVAILABLE = 503;
public static final int SC_GATEWAY_TIMEOUT = 504;
public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;

 

最后配置filterInvocationInterceptor:

<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
    <property name="authenticationManager" ref="authenticationManager" />
    <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager" />
    <property name="objectDefinitionSource">
        <value><![CDATA[
            CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
            PATTERN_TYPE_APACHE_ANT
            /secure.jsp=ROLE_SUPERVISOR
        ]]></value>
    </property>
</bean>

<bean id="httpRequestAccessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
    <property name="decisionVoters">
        <list>
            <bean class="org.acegisecurity.vote.RoleVoter"/>
        </list>
    </property>
</bean>

 注:FilterSecurityInterceptor是filterchain中比较复杂,也是比较核心的过滤器,主要负责授权的工作

spring通过HttpConfigurationBuilder类来为filter构造过滤器实例,代码片段如下:

	private void createFilterSecurityInterceptor(BeanReference authManager) {
		boolean useExpressions = FilterInvocationSecurityMetadataSourceParser
				.isUseExpressions(httpElt);
		RootBeanDefinition securityMds = FilterInvocationSecurityMetadataSourceParser
				.createSecurityMetadataSource(interceptUrls, addAllAuth, httpElt, pc);

		RootBeanDefinition accessDecisionMgr;
		ManagedList<BeanDefinition> voters = new ManagedList<BeanDefinition>(2);

		if (useExpressions) {
			//表达式模式,这里省略,不是本例重点
		}
		else {
			voters.add(GrantedAuthorityDefaultsParserUtils.registerWithDefaultRolePrefix(pc, RoleVoterBeanFactory.class));
			voters.add(new RootBeanDefinition(AuthenticatedVoter.class));
		}
		accessDecisionMgr = new RootBeanDefinition(AffirmativeBased.class);
		accessDecisionMgr.getConstructorArgumentValues().addGenericArgumentValue(voters);
		accessDecisionMgr.setSource(pc.extractSource(httpElt));

		// Set up the access manager reference for http
		String accessManagerId = httpElt.getAttribute(ATT_ACCESS_MGR);

		if (!StringUtils.hasText(accessManagerId)) {
			accessManagerId = pc.getReaderContext().generateBeanName(accessDecisionMgr);
			pc.registerBeanComponent(new BeanComponentDefinition(accessDecisionMgr,
					accessManagerId));
		}

		BeanDefinitionBuilder builder = BeanDefinitionBuilder
				.rootBeanDefinition(FilterSecurityInterceptor.class);

		builder.addPropertyReference("accessDecisionManager", accessManagerId);
		builder.addPropertyValue("authenticationManager", authManager);

		if ("false".equals(httpElt.getAttribute(ATT_ONCE_PER_REQUEST))) {
			builder.addPropertyValue("observeOncePerRequest", Boolean.FALSE);
		}

		builder.addPropertyValue("securityMetadataSource", securityMds);
		BeanDefinition fsiBean = builder.getBeanDefinition();
		String fsiId = pc.getReaderContext().generateBeanName(fsiBean);
		pc.registerBeanComponent(new BeanComponentDefinition(fsiBean, fsiId));

		// Create and register a DefaultWebInvocationPrivilegeEvaluator for use with
		// taglibs etc.
		BeanDefinition wipe = new RootBeanDefinition(
				DefaultWebInvocationPrivilegeEvaluator.class);
		wipe.getConstructorArgumentValues().addGenericArgumentValue(
				new RuntimeBeanReference(fsiId));

		pc.registerBeanComponent(new BeanComponentDefinition(wipe, pc.getReaderContext()
				.generateBeanName(wipe)));

		this.fsi = new RuntimeBeanReference(fsiId);
	}

 从上面的代码片段可以看出,在FilterInvocationSecurityMetadataSourceParser类中定义了一个静态方法用于处理鉴权元数据,代码片段如下:

	static RootBeanDefinition createSecurityMetadataSource(List<Element> interceptUrls,
			boolean addAllAuth, Element httpElt, ParserContext pc) {
		MatcherType matcherType = MatcherType.fromElement(httpElt);
		boolean useExpressions = isUseExpressions(httpElt);

		ManagedMap<BeanMetadataElement, BeanDefinition> requestToAttributesMap = parseInterceptUrlsForFilterInvocationRequestMap(
				matcherType, interceptUrls, useExpressions, addAllAuth, pc);
		BeanDefinitionBuilder fidsBuilder;

		if (useExpressions) {
			Element expressionHandlerElt = DomUtils.getChildElementByTagName(httpElt,
					Elements.EXPRESSION_HANDLER);
			String expressionHandlerRef = expressionHandlerElt == null ? null
					: expressionHandlerElt.getAttribute("ref");

			if (StringUtils.hasText(expressionHandlerRef)) {
				logger.info("Using bean '" + expressionHandlerRef
						+ "' as web SecurityExpressionHandler implementation");
			}
			else {
				expressionHandlerRef = registerDefaultExpressionHandler(pc);
			}

			fidsBuilder = BeanDefinitionBuilder
					.rootBeanDefinition(ExpressionBasedFilterInvocationSecurityMetadataSource.class);
			fidsBuilder.addConstructorArgValue(requestToAttributesMap);
			fidsBuilder.addConstructorArgReference(expressionHandlerRef);
		}
		else {
			fidsBuilder = BeanDefinitionBuilder
					.rootBeanDefinition(DefaultFilterInvocationSecurityMetadataSource.class);
			fidsBuilder.addConstructorArgValue(requestToAttributesMap);
		}

		fidsBuilder.getRawBeanDefinition().setSource(pc.extractSource(httpElt));

		return (RootBeanDefinition) fidsBuilder.getBeanDefinition();
	}

 

完整的spring-acegi.xml配置如下所示(完整路径:src/main/resources/META-INF/spring/spring-acegi.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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:webflow="http://www.springframework.org/schema/webflow-config"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
         http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.4.xsd"
	default-autowire="byName">
     <bean id ="filterChainProxy" class= "org.acegisecurity.util.FilterChainProxy">
            <property name ="filterInvocationDefinitionSource">
                 <value>
                     PATTERN_TYPE_APACHE_ANT
                     /**=basicProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
                 </value>
            </property>
     </bean>

     <bean id ="basicProcessingFilter" class= "org.acegisecurity.ui.basicauth.BasicProcessingFilter">
            <property name ="authenticationManager" ref= "authenticationManager" />
            <property name ="authenticationEntryPoint" ref= "basicProcessingFilterEntryPoint" />
     </bean>

     <bean id ="basicProcessingFilterEntryPoint" class= "org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint">
            <property name ="realmName" value="Acegi First Realm Name" />
     </bean>

     <bean id ="authenticationManager" class= "org.acegisecurity.providers.ProviderManager">
            <property name ="providers">
                 <list><ref bean="daoAuthenticationProvider" /></list>
            </property>
     </bean>

     <bean id ="daoAuthenticationProvider" class= "org.acegisecurity.providers.dao.DaoAuthenticationProvider">
            <property name ="userDetailsService" ref= "inMemDaoImpl" />
     </bean>

    <!-- 基于内存实现方式-->
     <bean id ="inMemDaoImpl" class= "org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
            <property name ="userMap">
                 <value>
                     test=1,ROLE_SUPERVISOR
                     zhangsan=1,ROLE_SUPERVISOR,disabled
                 </value>
            </property>
     </bean>

     <!-- exception filter -->
     <bean id ="exceptionTranslationFilter" class= "org.acegisecurity.ui.ExceptionTranslationFilter">
            <property name ="authenticationEntryPoint" ref= "basicProcessingFilterEntryPoint" />
     </bean>

   <bean id ="filterInvocationInterceptor" class= "org.acegisecurity.intercept.web.FilterSecurityInterceptor">
            <property name ="authenticationManager" ref= "authenticationManager" />
            <property name ="accessDecisionManager" ref= "httpRequestAccessDecisionManager" />
            <property name ="objectDefinitionSource">
                 <value ><![CDATA[
                     CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                     PATTERN_TYPE_APACHE_ANT
                     /secure.jsp=ROLE_SUPERVISOR
                 ]]></value>
            </property>
     </bean>

     <bean id ="httpRequestAccessDecisionManager" class= "org.acegisecurity.vote.AffirmativeBased">
            <property name ="decisionVoters">
                 <list><bean class= "org.acegisecurity.vote.RoleVoter" /></list>
            </property>
     </bean>
</beans>

 

对应的web.xml文件配置信息如下所示:

<?xml version="1.0" encoding= "UTF-8"?>  
<web-app xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns= "http://java.sun.com/xml/ns/javaee" xmlns:web= "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version= "2.5">
  <display-name>Archetype Created Web Application</display-name>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:META-INF/spring/spring-acegi.xml</param-value>
  </context-param>
  
  <filter>
    <filter-name>AcegiFilterChainProxy</filter-name>
    <filter-class>
                org.acegisecurity.util.FilterToBeanProxy
           </filter-class>
    <init-param>
      <param-name>targetBean</param-name>
      <param-value>filterChainProxy</param-value>
   </init-param>
 </filter>
  <filter-mapping>
    <filter-name>AcegiFilterChainProxy</filter-name>
    <url-pattern>/j_acegi_security_check</url-pattern>
 </filter-mapping>
  <filter-mapping>
    <filter-name>AcegiFilterChainProxy</filter-name>
    <url-pattern>/j_acegi_logout</url-pattern>
 </filter-mapping>
  <filter-mapping>
    <filter-name>AcegiFilterChainProxy</filter-name>
    <url-pattern>*.do</url-pattern>
 </filter-mapping>
  <filter-mapping>
    <filter-name>AcegiFilterChainProxy</filter-name>
    <url-pattern>*.jsp</url-pattern>
 </filter-mapping>
  <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>

  <listener>
       <listener-class>
        org.springframework.web.context.ContextLoaderListener
      </listener-class>
  </listener>
</web-app>

 

不失完整性,用于构建工程用到的指令如下:

mvn archetype:generate -DgroupId=com.myteay -DartifactId=rest-common-acegi -Dversion=1.0.0 -Dpackage=com.myteay -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeGroupId=org.apache.maven.archetypes  -DinteractiveMode=false

 

方便使用起见,贴出工程用到的完整pom

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.myteay</groupId>
  <artifactId>rest-common-acegi</artifactId>
  <packaging>war</packaging>
  <version>1.0.0</version>
  <name>rest-common-acegi Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
		<dependency>  
		    <groupId>org.springframework.security</groupId>  
		    <artifactId>spring-security-core</artifactId>  
		    <version>4.2.2.RELEASE</version>  
		</dependency> 
		
		<dependency>  
		    <groupId>org.springframework.security</groupId>  
		    <artifactId>spring-security-web</artifactId>  
		    <version>4.2.2.RELEASE</version>  
		</dependency>

		<dependency>  
		    <groupId>org.springframework.security</groupId>  
		    <artifactId>spring-security-config</artifactId>  
		    <version>4.2.2.RELEASE</version>  
		    <scope>runtime</scope>  
		</dependency>
		<dependency>
	        <groupId>org.apache.geronimo.specs</groupId>
	        <artifactId>geronimo-servlet_2.4_spec</artifactId>
	        <version>1.1.1</version>
	        <scope>provided</scope>
	    </dependency>
		<!-- spring dependency start -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-expression</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-oxm</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>4.2.2.RELEASE</version>
		</dependency>
		<!-- spring dependency end -->

		<!-- unit test start -->
		<dependency>
			<groupId>jmock</groupId>
			<artifactId>jmock</artifactId>
			<version>1.2.0</version>
		</dependency>
		<dependency>
			<groupId>jmock</groupId>
			<artifactId>jmock-cglib</artifactId>
			<version>1.2.0</version>
		</dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
	<dependency>
		<groupId>org.acegisecurity</groupId>
		<artifactId>acegi-security</artifactId>
		<version>1.0.7</version>
	</dependency>
  </dependencies>
  <build>
    <finalName>rest-common-acegi</finalName>
    <plugins>
		<plugin>
			<groupId>org.mortbay.jetty</groupId>
			<artifactId>maven-jetty-plugin</artifactId>
			<version>6.1.26</version>
			<configuration>
				<scanIntervalSeconds>3</scanIntervalSeconds>
				<connectors>
					<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
						<port>80</port>
					</connector>
				</connectors>
				<scanTargetPatterns>
					<scanTargetPattern>
						<directory>src/main/webapp/WEB-INF</directory>
						<excludes>
							<exclude>**/*.jsp</exclude>
						</excludes>
						<includes>
							<include>**/*.properties</include>
							<include>**/*.xml</include>
						</includes>
					</scanTargetPattern>
				</scanTargetPatterns>
			</configuration>
		</plugin>
    </plugins>
  </build>
</project>

 

 

 

 

 

 

0
1
分享到:
评论

相关推荐

    spring acegi 详细文档

    首先,Acegi的主要目标是保护Spring应用免受非法访问,它提供了丰富的功能来实现用户认证、会话管理、权限控制以及安全相关的异常处理。Acegi的核心组件包括`AuthenticationManager`、`AccessDecisionManager`和`...

    Spring Acegi权限控制

    Spring Acegi权限控制是Spring框架中用于实现Web应用安全的一种解决方案。...尽管Acegi Security已经被Spring Security取代,但其核心理念和使用方式仍然对理解现代Web应用的安全管理有着重要的参考价值。

    Spring ACEGI手册(部份)

    **Spring ACEGI安全框架简介** Spring ACEGI是Spring Security的前身,它是一个强大的、高度可配置的安全框架,专为Java企业级应用设计。这个框架旨在提供全面的身份验证、授权和服务层安全功能,允许开发者轻松地...

    Spring源代码解析(九):Spring_Acegi框架鉴权的实现.doc

    在Spring框架中,Acegi(现在已经演变为Spring Security)是一个强大的安全管理组件,它提供了认证、授权等核心安全功能。在Spring_Acegi框架鉴权的实现中,我们主要关注的是如何处理用户的登录验证以及在验证成功或...

    Spring acegi 3 文档

    在 Spring Acegi 3 中,身份验证过程是核心功能之一。它支持多种认证方式,包括基于表单的登录、HTTP 基本身份验证和 LDAP 集成。开发者可以自定义认证策略,例如实现 `AuthenticationProvider` 接口来创建自己的...

    spring Acegi例子,很简单的一个acegi实例,容易理解

    Spring Acegi是一个安全框架,它为Spring应用提供了全面的安全管理解决方案。这个例子是为初学者设计的,旨在帮助他们快速理解和应用Acegi框架。Acegi(现在已被Spring Security替代)在Spring应用程序中提供了身份...

    Spring Acegi(2)

    4. **Filter Security Interceptor (FSI)**:Acegi的核心组件之一,它是Spring MVC中的一个拦截器,负责处理请求的安全过滤。通过配置XML或注解,我们可以指定哪些URL需要保护,以及需要哪种级别的访问控制。 5. **...

    spring acegi 使用工程demo

    Spring Acegi是一个安全框架,它为Spring应用提供了全面的安全管理功能。这个"spring acegi 使用工程demo"显然是一个示例项目,旨在帮助开发者理解和实践如何在Spring应用中集成和使用Acegi安全框架。 首先,Acegi...

    spring acegi

    尽管Spring Acegi已经被弃用,但它的核心理念和设计模式对Spring Security的发展产生了深远影响。 **一、认证与授权** Spring Acegi的主要功能是处理应用的认证和授权。认证是指确认用户的身份,通常通过用户名和...

    Spring源代码解析(十):Spring_Acegi框架授权的实现.doc

    在Spring框架中,Acegi(现在已经并入Spring Security)是一个强大的安全管理组件,它提供了认证和授权功能。在本文中,我们将深入探讨Spring_Acegi框架如何实现授权机制,特别是通过`FilterSecurityInterceptor`来...

    Spring Acegi

    总结,Spring Acegi 是一个强大的安全框架,为 Spring 应用提供了全面的安全管理。虽然已经被 Spring Security 取代,但理解其原理对于深入学习 Spring Security 或其他安全框架仍具有重要的参考价值。在实际开发中...

    spring的acegi应用

    标题“spring的acegi应用”指的是在Spring框架中使用Acegi安全模块进行权限管理和用户认证的一个主题。Acegi是Spring早期的一个安全组件,后来发展成为Spring Security,是Spring生态系统中的重要部分,用于提供全面...

    spring acegi 学习心得

    前段时间复习了spring怎么做权限的技术,spring acegi 学习心得.记下来勉励自己.

    实战Acegi:使用Acegi作为基于Spring框架的WEB应用的安全框架

    Acegi是一个专门为SpringFramework应用提供安全机制的开放源代码项目,全称为Acegi Security System for Spring,当前版本为 0.8.3。它使用了Spring的方式提供了安全和认证安全服务,包括使用Bean Context,拦截器和...

    基于spring的Acegi安全框架认证与授权的分析及扩展.pdf

    ### 基于Spring的Acegi安全框架认证与授权的分析及扩展 #### 1. Acegi安全框架的概述 Acegi(后更名为Spring Security)是Spring框架中的一个子项目,专注于提供强大的安全功能,包括认证、授权以及保护web应用...

    spring_acegi精彩实例,带MYSQL数据库脚本,保证能运行

    spring_acegi精彩实例,带MYSQL数据库脚本,保证能运行 spring_acegi精彩实例,带MYSQL数据库脚本,保证能运行 spring_acegi精彩实例,带MYSQL数据库脚本,保证能运行 spring_acegi精彩实例,带MYSQL数据库脚本,...

    Spring源代码解析

    Spring源代码解析(一):IOC容器 Spring源代码解析(二):IoC容器在Web容器中的启动 Spring源代码解析(三)...Spring源代码解析(九):Spring Acegi框架鉴权的实现 Spring源代码解析(十):Spring Acegi框架授权的实现

Global site tag (gtag.js) - Google Analytics