一、查看 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
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 .登錄的時候執(zhí)行的過濾為 authenticationProcessingFilter ,查看其實現(xiàn)為 org.bookStore.test.plugins.security.UserAuthenticationProcessingFilter ,該類繼承自 org.acegisecurity.ui.webapp.AuthenticationProcessingFilter ,又繼承自 org.acegisecurity.ui.AbstractProcessingFilter ,這時候看到了 doFilter() 該方法取了 web 層傳過來的 request 和 response ,然后對登錄路徑執(zhí)行了判斷等操作,接下來執(zhí)行至 authResult = attemptAuthentication(httpRequest); 2 .從類繼承關(guān)系上找到該方法的實現(xiàn)來自 AuthenticationProcessingFilter ,執(zhí)行的邏輯為先取出 web 層傳過來的用戶名和密碼接著將得到的信息包裝為 UsernamePasswordAuthenticationToken :
public
UsernamePasswordAuthenticationToken(Object principal, Object credentials) {
super
(
null
);
this
.
principal
= principal;
this
.
credentials
= credentials;
setAuthenticated(
false
);
} 3 .接下來執(zhí)行了 setDetails(request, authRequest); 將 request 實例賦給 authRequest 的屬性。 4 .調(diào)用 authenticationManager 的 authenticate(authRequest) 方法。 5 .程序轉(zhuǎn)至 authenticationManager 內(nèi)執(zhí)行。該類繼承自 org.acegisecurity. AbstractAuthenticationManager ,執(zhí)行方法 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 該方法執(zhí)行了其 providers 中的方法 authenticate(Authentication authentication)
6
.此方法中調(diào)用了
retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication)
該方法內(nèi)按
web
層用戶輸入的用戶名和密碼從數(shù)據(jù)庫內(nèi)比較是否有該用戶,如果有則將其
user
表內(nèi)對應(yīng)的信息包裝為
UserDetail(
接口
,
實際為
User
的實例
)
的
List
對象,并將該用戶相應(yīng)的權(quán)限包裝為
GrantedAuthorityImpl
對象的
List
集合對象。至此程序返回至(
3.
)繼續(xù)執(zhí)行
7
.繼續(xù)執(zhí)行
org.acegisecurity.ui.AbstractProcessingFilter
的
successfulAuthentication(
HttpServletRequest request,
HttpServletResponse response,
Authentication authResult){
......
SecurityContextHolder.getContext().setAuthentication(authResult);//
將包裝好的
UsernamePasswordAuthenticationToken
對象保存至系統(tǒng)上下文
......
} 8 .登錄執(zhí)行完畢。 |
|