【shiro】登录经历的流程(执行ShiroAccountRealm doGetAuthenticationInfo经历的过程)
http://jinnianshilongnian.iteye.com/blog/2025656 拦截器机制。
在这里
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean getShiroFilter() {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager());
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setSuccessUrl("/index");
Map<String, Filter> filters = new HashMap<>();
filters.put("authc", getFormAuthenticationCaptchaFilter()); //******************************//
filters.put("logout", getLogoutFilter());
shiroFilterFactoryBean.setFilters(filters);
shiroFilterFactoryBean.setFilterChainDefinitionMap(getFilterChainDefinitionMap());
return shiroFilterFactoryBean;
}
private Map<String, String> getFilterChainDefinitionMap() {
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
filterChainDefinitionMap.put("/login", "authc"); //******************************//
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/druid", "anon");
filterChainDefinitionMap.put("/olv3", "anon");
filterChainDefinitionMap.put("/*", "anon");
return filterChainDefinitionMap;
}
————————————————————————————————————————————————————————
FormAuthenticationCaptchaFilter
继承自 FormAuthenticationFilter
继承自 AuthenticatingFilter
继承自 AuthenticationFilter
继承自 AccessControlFilter
isAccessAllowed和onAccessDenied是AccessControlFilter的方法
【-A-】调用 FormAuthenticationFilter onAccessDenied 方法
return executeLogin(request, response);
【-B-】调用 AuthenticatingFilter executeLogin 方法
AuthenticationToken token = createToken(request, response);
Subject subject = getSubject(request, response);
subject.login(token);
【-C-】Subject是一个接口
实际调用DelegatingSubject的login方法
Subject subject = securityManager.login(this, token);
【-D-】SecurityManager是一个接口
实际调用DefaultSecurityManager的login方法
AuthenticationInfo info;
info = authenticate(token);
【-E-】调用 AuthenticatingSecurityManager 的authenticate方法
return调用Authenticator接口的authenticate方法,
实际调用AbstractAuthenticator类的authenticate方法,
AuthenticationInfo info;
info = doAuthenticate(token);
【-F-】调用ModularRealmAuthenticator的doAuthenticate方法,
调用assertRealmsConfigured();
Collection<Realm> realms = getRealms();
if (realms.size() == 1) {
return doSingleRealmAuthentication(realms.iterator().next(), authenticationToken);
} else {
return doMultiRealmAuthentication(realms, authenticationToken);
}
【-G-】调用doSingleRealmAuthentication(Realm realm, AuthenticationToken token)
AuthenticationInfo info = realm.getAuthenticationInfo(token);
【-H-】调用Realm接口的getAuthenticationInfo(token)方法
实际调用AuthenticatingRealm的getAuthenticationInfo(token)方法
AuthenticationInfo info = getCachedAuthenticationInfo(token);
if (info == null) {
//otherwise not cached, perform the lookup:
info = doGetAuthenticationInfo(token);
【-I-】调用ShiroAccountRealm的doGetAuthenticationInfo(token)方法
而此方法是自己写的!!!
AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(username, user.getPassword(), this.getName());
返回authcInfo 继续再往上返回。