一、查看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" />
<beanclass="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
<property name="key" value="javajohnKey"/>
</bean>
<beanclass="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">
<beanclass="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
<property name="cache">
<beanclass="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<beanclass="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
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.登录执行完毕。
联系客服