- 浏览: 44238 次
- 性别:
- 来自: 福州
文章分类
最新评论
在Acegi的认证filter中,首先是org.acegisecurity.ui.webapp.AuthenticationProcessingFilter
这个类是用来对登录者进行认证。它的doFilter方法中调用了attemptAuthentication(httpRequest)方法,并且如果返回的结果说明有效,则把经过认证的信息通过successfulAuthentication(httpRequest, httpResponse, authResult)保存起来。 其中代码如下:
attemptAuthentication方法是用来把登录者填写的用户名、密码信息转化为UsernamePasswordAuthenticationToken类型,并通过AuthenticationManager的authenticate方法进行作业。代码如下:
其中authenticate(authRequest)代码如下,其目的是通过各个实现类来实现认证。
其中doAuthentication(authRequest)方法在ProviderManager中定义,因为其中提供了多个provider,所以需要遍历各个验证器。
对认证管理器中提供的各个provider进行判断,如果有任何一个通过验证,那么就返回,并发布成功的event,否则抛出异常。
而其中privider中进行的验证根据各个实现而不同,例如对于DaoAuthenticationProvider,其提供的authenticate是通过用户名和UserDetailsService来获取用户资料信息,并且在各个检验条件合格后把认证信息绑定并返回。代码如下:
而对于RememberMeAuthenticationProvider,其提供的验证方式是与在自动登录时保存的key值有关。代码如下:
这样,如果在自动登录时保存的用户名、密码等信息经过了系统认证,则也允许登录。
这个类是用来对登录者进行认证。它的doFilter方法中调用了attemptAuthentication(httpRequest)方法,并且如果返回的结果说明有效,则把经过认证的信息通过successfulAuthentication(httpRequest, httpResponse, authResult)保存起来。 其中代码如下:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (!(request instanceof HttpServletRequest)) { throw new ServletException("Can only process HttpServletRequest"); } if (!(response instanceof HttpServletResponse)) { throw new ServletException("Can only process HttpServletResponse"); } HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; if (requiresAuthentication(httpRequest, httpResponse)) { if (logger.isDebugEnabled()) { logger.debug("Request is to process authentication"); } Authentication authResult; try { onPreAuthentication(httpRequest, httpResponse); authResult = attemptAuthentication(httpRequest); } catch (AuthenticationException failed) { // Authentication failed unsuccessfulAuthentication(httpRequest, httpResponse, failed); return; } // Authentication success if (continueChainBeforeSuccessfulAuthentication) { chain.doFilter(request, response); } successfulAuthentication(httpRequest, httpResponse, authResult); return; } chain.doFilter(request, response); }
attemptAuthentication方法是用来把登录者填写的用户名、密码信息转化为UsernamePasswordAuthenticationToken类型,并通过AuthenticationManager的authenticate方法进行作业。代码如下:
public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException { String username = obtainUsername(request); String password = obtainPassword(request); if (username == null) { username = ""; } if (password == null) { password = ""; } UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); // Place the last username attempted into HttpSession for views request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username); // Allow subclasses to set the "details" property setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); }
其中authenticate(authRequest)代码如下,其目的是通过各个实现类来实现认证。
public final Authentication authenticate(Authentication authRequest) throws AuthenticationException { try { Authentication authResult = doAuthentication(authRequest); copyDetails(authRequest, authResult); return authResult; } catch (AuthenticationException e) { e.setAuthentication(authRequest); throw e; } }
其中doAuthentication(authRequest)方法在ProviderManager中定义,因为其中提供了多个provider,所以需要遍历各个验证器。
public Authentication doAuthentication(Authentication authentication) throws AuthenticationException { Iterator iter = providers.iterator(); Class toTest = authentication.getClass(); AuthenticationException lastException = null; while (iter.hasNext()) { AuthenticationProvider provider = (AuthenticationProvider) iter.next(); if (provider.supports(toTest)) { logger.debug("Authentication attempt using " + provider.getClass().getName()); Authentication result = null; try { result = provider.authenticate(authentication); sessionController.checkAuthenticationAllowed(result); } catch (AuthenticationException ae) { lastException = ae; result = null; } if (result != null) { sessionController.registerSuccessfulAuthentication(result); publishEvent(new AuthenticationSuccessEvent(result)); return result; } } } if (lastException == null) { lastException = new ProviderNotFoundException(messages.getMessage("ProviderManager.providerNotFound", new Object[] {toTest.getName()}, "No AuthenticationProvider found for {0}")); } // Publish the event String className = exceptionMappings.getProperty(lastException.getClass().getName()); AbstractAuthenticationEvent event = null; if (className != null) { try { Class clazz = getClass().getClassLoader().loadClass(className); Constructor constructor = clazz.getConstructor(new Class[] { Authentication.class, AuthenticationException.class }); Object obj = constructor.newInstance(new Object[] {authentication, lastException}); Assert.isInstanceOf(AbstractAuthenticationEvent.class, obj, "Must be an AbstractAuthenticationEvent"); event = (AbstractAuthenticationEvent) obj; } catch (ClassNotFoundException ignored) {} catch (NoSuchMethodException ignored) {} catch (IllegalAccessException ignored) {} catch (InstantiationException ignored) {} catch (InvocationTargetException ignored) {} } if (event != null) { publishEvent(event); } else { if (logger.isDebugEnabled()) { logger.debug("No event was found for the exception " + lastException.getClass().getName()); } } // Throw the exception throw lastException; }
对认证管理器中提供的各个provider进行判断,如果有任何一个通过验证,那么就返回,并发布成功的event,否则抛出异常。
而其中privider中进行的验证根据各个实现而不同,例如对于DaoAuthenticationProvider,其提供的authenticate是通过用户名和UserDetailsService来获取用户资料信息,并且在各个检验条件合格后把认证信息绑定并返回。代码如下:
public Authentication authenticate(Authentication authentication) throws AuthenticationException { Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication, messages.getMessage("AbstractUserDetailsAuthenticationProvider.onlySupports", "Only UsernamePasswordAuthenticationToken is supported")); // Determine username String username = (authentication.getPrincipal() == null) ? "NONE_PROVIDED" : authentication.getName(); boolean cacheWasUsed = true; UserDetails user = this.userCache.getUserFromCache(username); if (user == null) { cacheWasUsed = false; try { user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication); } catch (UsernameNotFoundException notFound) { if (hideUserNotFoundExceptions) { throw new BadCredentialsException(messages.getMessage( "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")); } else { throw notFound; } } Assert.notNull(user, "retrieveUser returned null - a violation of the interface contract"); } if (!user.isAccountNonLocked()) { throw new LockedException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.locked", "User account is locked")); } if (!user.isEnabled()) { throw new DisabledException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.disabled", "User is disabled")); } if (!user.isAccountNonExpired()) { throw new AccountExpiredException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.expired", "User account has expired")); } // This check must come here, as we don't want to tell users // about account status unless they presented the correct credentials try { additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication); } catch (AuthenticationException exception) { if(cacheWasUsed) { // There was a problem, so try again after checking // we're using latest data (ie not from the cache) cacheWasUsed = false; user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication); additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication); } else { throw exception; } } if (!user.isCredentialsNonExpired()) { throw new CredentialsExpiredException(messages.getMessage( "AbstractUserDetailsAuthenticationProvider.credentialsExpired", "User credentials have expired")); } if (!cacheWasUsed) { this.userCache.putUserInCache(user); } Object principalToReturn = user; if (forcePrincipalAsString) { principalToReturn = user.getUsername(); } return createSuccessAuthentication(principalToReturn, authentication, user); }
而对于RememberMeAuthenticationProvider,其提供的验证方式是与在自动登录时保存的key值有关。代码如下:
public Authentication authenticate(Authentication authentication) throws AuthenticationException { if (!supports(authentication.getClass())) { return null; } if (this.key.hashCode() != ((RememberMeAuthenticationToken) authentication).getKeyHash()) { throw new BadCredentialsException(messages.getMessage("RememberMeAuthenticationProvider.incorrectKey", "The presented RememberMeAuthenticationToken does not contain the expected key")); } return authentication; }
这样,如果在自动登录时保存的用户名、密码等信息经过了系统认证,则也允许登录。
相关推荐
前段时间复习了spring怎么做权限的技术,spring acegi 学习心得.记下来勉励自己.
"学习Acegi-认证(authentication) - Acegi 专栏 - JavaEye知识库.mht"和"Acegi学习小结 - Acegi 专栏 - JavaEye知识库.mht"可能提供了更深入的认证学习材料和作者的学习心得,包括可能遇到的问题和解决方案,这对于...
Acegi 是一个强大的 Java 安全框架,专用于系统安全编程,尤其在处理认证和授权方面表现出色。在本文中,我们将深入探讨 Acegi 的基本概念、如何设置以及它如何与 Spring 框架集成。 首先,让我们了解 Acegi 的核心...
这个压缩包包含了Acegi的示例代码和一个学习资源,对于初学者来说是非常宝贵的资料。 首先,让我们深入理解Acegi的核心概念: 1. **身份验证(Authentication)**:Acegi允许你实现自定义的身份验证机制,这包括...
Acegi学习是一个深入探讨Java平台上的安全性框架的主题。Acegi是Spring Framework的早期安全模块,为基于Spring的应用程序提供了强大的身份验证和授权功能。在Java世界中,安全性和权限管理是构建任何企业级应用不可...
通过学习Acegi,我们可以了解到Web应用安全的基本思路和实践方法,这对于理解现代的Spring Security框架非常有帮助。虽然Acegi已经不再更新,但它的理念和架构仍对现代安全框架设计产生深远影响。
Acegi 是一个在Java开发领域,特别是Spring框架中曾经广泛使用的安全组件,全称为Acegi Security。...学习Acegi可以帮助我们更好地理解Spring Security的工作原理,从而提升我们的应用安全开发能力。
由于文章内容是关于acegi pdf学习的参考文档,其中包含了大量关于Acegi安全系统的技术细节,因此以下将详细阐述文档中提及的关键知识点。 首先,Acegi安全系统是一个基于Spring框架的安全解决方案。文档开头简要...
Acegi是Spring Security的前身,它是一个用于Java企业级应用的安全框架,主要处理身份验证、授权和会话管理。在本文中,我们将深入探讨Acegi的学习指南,通过实例来理解其核心概念和功能。 首先,我们需要了解Acegi...
Acegi学习 Acegi是Spring Security的前身,它是一个强大且灵活的安全框架,用于Java企业级应用程序。在本文中,我们将深入探讨Acegi的核心概念、功能以及如何在实际项目中应用它。 首先,我们需要理解Acegi的核心...
通过深入学习Acegi,你可以了解Spring Security的基本架构和原理,这对于理解现代的Spring Security配置和使用非常有帮助。尽管Acegi已不再更新,但其思想和技术仍在Spring Security中得到沿用和发展。如果你正在...
### Acegi学习笔记详解 #### 一、Acegi Security概览 **Acegi Security**,作为Spring Security的前身,是一个深度融入Spring Framework的安全框架,它为开发者提供了一套全面的安全解决方案,尤其在Web应用程序中...
Acegi Security是一个专门为Spring框架设计的权限控制框架,旨在为基于J2EE的企业级应用程序提供全面的安全服务。这个框架解决了J2EE规范中安全性配置不便于移植的问题,使得应用程序的安全设置能够在不同服务器环境...
Spring Acegi是一个安全框架,它为Spring应用提供了一套强大的身份验证和授权机制。这个框架在Spring Security(之前称为Spring Security)之前被广泛使用。在本文中,我们将深入探讨Spring Acegi的核心概念、功能和...
Acegi Security,现称为Spring Security,是一个强大的安全框架,主要用于基于Spring的企业级应用。它通过Spring的依赖注入(IoC)和面向切面编程(AOP)功能,提供了声明式的安全访问控制。Acegi能够实现精细的权限...
AceGI,全称为Acegi ...理解Acegi对于学习和使用Spring Security仍然大有裨益,因为它可以帮助我们更好地理解Web应用程序的安全设计和实现。在实际开发中,掌握Acegi的相关知识可以提升我们构建安全系统的专业能力。
Acegi是一个专门为SpringFramework应用提供安全机制的开放源代码项目,全称为Acegi Security System for Spring,当前版本为 0.8.3。它使用了Spring的方式提供了安全和认证安全服务,包括使用Bean Context,拦截器和...
Spring Acegi是一个安全框架,它为Spring应用提供了全面的安全管理解决方案。这个例子是为初学者设计的,旨在帮助他们快速理解和应用Acegi框架。Acegi(现在已被Spring Security替代)在Spring应用程序中提供了身份...
Acegi权限控制学习笔记 Acegi安全框架是Spring Security的前身,它提供了一种强大的、灵活的、基于组件的安全解决方案,用于实现企业级应用的安全控制。在这个学习笔记中,我们将探讨两个关键点:身份认证成功后的...