acegi
				
				源码学习之用户登录篇
		
		
				一、查看
				applicationContext-acegi-security.xml
				配置文件,涉及到登录的配置为:
		
		
				
						 1
				.
				
						
						
						
				
		
		
				<
				bean 
				id
				=
				"authenticationProcessingFilter"
				
						class
						=
						"org.javajohn.test.plugins.security.UserAuthenticationProcessingFilter"
						>
						
						
				
		
		
				
						        
				
				<
				property 
				name
				=
				"authenticationManager" 
				ref
				=
				"authenticationManager"
				/>
				
						
						
				
		
		
				
						        
				
				<
				property 
				name
				=
				"authenticationFailureUrl"
				>
				
						
						
				
		
		
				
						            
				
				<
				value
				>
				/login.jsp?login_error=1
				</
				value
				>
				
						
						
				
		
		
				
						        
				
				</
				property
				>
				
						
						
				
		
		
				
						        
				
				<
				property 
				name
				=
				"defaultTargetUrl"
				>
				
						
						
				
		
		
				
						            
				
				<
				value
				>
				/index.jsp
				</
				value
				>
				
						
						
				
		
		
				
						        
				
				</
				property
				>
				
						
						
				
		
		
				
						        
				
				<
				property 
				name
				=
				"filterProcessesUrl"
				>
				
						
						
				
		
		
				
						            
				
				<
				value
				>
				/j_acegi_security_check
				</
				value
				>
				
						
						
				
		
		
				
						        
				
				</
				property
				>
				
						
						
				
		
		
				
						        
				
				<
				property 
				name
				=
				"userManager" 
				ref
				=
				"userManager"
				/>
				
						
						
				
		
		
				
						        
				
				<
				property 
				name
				=
				"rememberMeServices" 
				ref
				=
				"rememberMeServices"
				/>
				
						
						
				
		
		
				
						        
				
				<
				property 
				name
				=
				"exceptionMappings"
				>
				
						
						
				
		
		
				
						            
				
				<
				value
				>
				
						
						
				
		
		
				
						                org.acegisecurity.AuthenticationException=/login.jsp?login_error=user_psw_error
				
						
						
				
		
		
				
						                org.acegisecurity.concurrent.ConcurrentLoginException=/login.jsp?login_error=too_many_user_error
				
						
						
				
		
		
				
						        
						    
				
				</
				value
				>
				
						
						
				
		
		
				
						        
				
				</
				property
				>
				
						
						
				
		
		
				</
				bean
				>
		
		
				
						 
				
		
		
				
						 
				
		
		
				2
				.
				<
				bean 
				id
				=
				"authenticationManager"
				
						
						
				
		
		
				
						       
				
				class
				=
				"org.acegisecurity.providers.ProviderManager"
				>
				
						
						
				
		
		
				
						       
				
				<
				property 
				name
				=
				"providers"
				>
				
						
						
				
		
		
				
						           
				
				<
				list
				>
				
						
						
				
		
		
				
						              
				
				<
				ref 
				local
				=
				"daoAuthenticationProvider" 
				/>
				
						
						
				
		
		
				
						              
				
				<
				bean
				
						class
						=
						"org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider"
						>
						
						
				
		
		
				
						                  
				
				<
				property 
				name
				=
				"key" 
				value
				=
				"javajohnKey"
				/>
				
						
						
				
		
		
				
						              
				
				</
				bean
				>
				
						
						
				
		
		
				
						              
				
				<
				bean
				
						class
						=
						"org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider"
						>
						
						
				
		
		
				
						                  
				
				<
				property 
				name
				=
				"key" 
				value
				=
				"javajohnKey"
				/>
				
						
						
				
		
		
				
						              
				
				</
				bean
				>
				
						
						
				
		
		
				
						           
				
				</
				list
				>
				
						
						
				
		
		
				
						       
				
				</
				property
				>
				
						   
				
				
						
						
				
		
		
				
						    
				
				</
				bean
				>
		
		
				
						 
				
		
		
				3
				.
		
		
				<
				bean 
				id
				=
				"daoAuthenticationProvider"
				
						class
						=
						"org.acegisecurity.providers.dao.DaoAuthenticationProvider"
						>
						
						
				
		
		
				
						       
				
				<
				property 
				name
				=
				"userDetailsService" 
				ref
				=
				"jdbcDaoImpl"
				/>
				
						
						
				
		
		
				
						       
				
				<
				property 
				name
				=
				"userCache"
				>
				
						
						
				
		
		
				
						           
				
				<
				bean
				
						class
						=
						"org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache"
						>
						
						
				
		
		
				
						              
				
				<
				property 
				name
				=
				"cache"
				>
				
						
						
				
		
		
				
						                  
				
				<
				bean
				
						class
						=
						"org.springframework.cache.ehcache.EhCacheFactoryBean"
						>
						
						
				
		
		
				
						                     
				
				<
				property 
				name
				=
				"cacheManager"
				>
				
						
						
				
		
		
				
						                         
				
				<
				bean
				
						class
						=
						"org.springframework.cache.ehcache.EhCacheManagerFactoryBean" 
						/>
						
						
				
		
		
				
						                     
				
				</
				property
				>
				
						
						
				
		
		
				
						                     
				
				<
				property 
				name
				=
				"cacheName" 
				value
				=
				"userCache"
				/>
				
						
						
				
		
		
				
						                  
				
				</
				bean
				>
				
						
						
				
		
		
				
						              
				
				</
				property
				>
				
						
						
				
		
		
				
						           
				
				</
				bean
				>
				
						
						
				
		
		
				
						       
				
				</
				property
				>
				
						
						
				
		
		
				
						       
				
				<
				property 
				name
				=
				"passwordEncoder" 
				ref
				=
				"passwordEncoder"
				/>
				
						
						
				
		
		
				
						    
				
				</
				bean
				>
		
		
				
						 
				
		
		
				
						 
				
		
		
				4
				.
				
						
						
				
				<
				bean 
				id
				=
				"jdbcDaoImpl"
				
						
						
				
		
		
				
						          
				
				class
				=
				"org.acegisecurity.userdetails.jdbc.JdbcDaoImpl"
				>
				
						
						
				
		
		
				
						        
				
				<
				property 
				name
				=
				"dataSource" 
				ref
				=
				"dataSource"
				/>
				
						
						
				
		
		
				
						        
				
				<
				property 
				name
				=
				"usersByUsernameQuery"
				>
				
						
						
				
		
		
				
						            
				
				<
				value
				>
				
						
						
				
		
		
				
						                select loginid,passwd,1 from users where status='1' and loginid = ?
				
						
						
				
		
		
				
						            
				
				</
				value
				>
				
						
						
				
		
		
				
						        
				
				</
				property
				>
				
						
						
				
		
		
				
						        
				
				<
				property 
				name
				=
				"authoritiesByUsernameQuery"
				>
				
						
						
				
		
		
				
						            
				
				<
				value
				>
				
						
						
				
		
		
				
						                select u.loginid,p.name from 
				
						
						
				
		
		
				
						                users u,roles r,permissions p,user_role ur,role_permis rp 
				
						
						
				
		
		
				
						                where 
				
						
						
				
		
		
				
						                u.id=ur.user_id and 
				
						
						
				
		
		
				
						                r.id=ur.role_id and 
				
						
						
				
		
		
				
						                p.id=rp.permis_id and 
				
						
						
				
		
		
				
						                r.id=rp.role_id and 
				
						
						
				
		
		
				
						                p.status='1' and u.loginid=?
				
						
						
				
		
		
				
						            
				
				</
				value
				>
				
						
						
				
		
		
				
						        
				
				</
				property
				>
				
						
						
				
		
		
				</
				bean
				>
		
		
				
						 
				
		
		
				
						 
				
		
		
				二、程序流程:
		
		
				1
				.登录的时候执行的过滤为
				authenticationProcessingFilter
				,查看其实现为
				org.bookStore.test.plugins.security.UserAuthenticationProcessingFilter
				,该类继承自
				org.acegisecurity.ui.webapp.AuthenticationProcessingFilter
				,又继承自
				org.acegisecurity.ui.AbstractProcessingFilter
				,这时候看到了
				doFilter()
				该方法取了
				web
				层传过来的
				request
				和
				response
				,然后对登录路径执行了判断等操作,接下来执行至
				authResult = attemptAuthentication(httpRequest);
		
		
				2
				.从类继承关系上找到该方法的实现来自
				AuthenticationProcessingFilter
				,执行的逻辑为先取出
				web
				层传过来的用户名和密码接着将得到的信息包装为
				UsernamePasswordAuthenticationToken
				:
		
		
				
						public
				
				 UsernamePasswordAuthenticationToken(Object principal, Object credentials) {
				
						
						
				
		
		
				
						    
				
				
						super
				
				(
				
						null
				
				);
				
						
						
				
		
		
				
						    
				
				
						this
				
				.
				principal
				 = principal;     
				
						
						
				
		
		
				
						    
				
				
						this
				
				.
				
						credentials
				
				 = credentials;
				
						
						
				
		
		
				
						    setAuthenticated(
				
						false
				
				);
				
						
						
				
		
		
				}
		
		
				3
				.接下来执行了
				setDetails(request, authRequest);
				将
				request
				实例赋给
				authRequest
				的属性。
		
		
				4
				.调用
				authenticationManager
				的
				authenticate(authRequest)
				方法。
		
		
				5
				.程序转至
				authenticationManager
				内执行。该类继承自
				org.acegisecurity. AbstractAuthenticationManager
				,执行方法
				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
				该方法执行了其
				providers
				中的方法
				authenticate(Authentication authentication)
		
		
				6
				.此方法中调用了
				retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication)
				该方法内按
				web
				层用户输入的用户名和密码从数据库内比较是否有该用户,如果有则将其
				user
				表内对应的信息包装为
				UserDetail(
				接口
				,
				实际为
				User
				的实例
				)
				的
				List
				对象,并将该用户相应的权限包装为
				GrantedAuthorityImpl
				对象的
				List
				集合对象。至此程序返回至(
				3.
				)继续执行
				
						
						
				
		
		
				7
				.继续执行
				org.acegisecurity.ui.AbstractProcessingFilter
				的
				successfulAuthentication(
		
		
				HttpServletRequest request, 
		
		
				HttpServletResponse response, 
		
		
				Authentication authResult){
		
		
				
						    ......
		
		
				SecurityContextHolder.getContext().setAuthentication(authResult);//
				将包装好的
				UsernamePasswordAuthenticationToken
				对象保存至系统上下文
				
						
						
				
		
		
				......
		
		
				}
		
		
				8
				.登录执行完毕。