SecurityUtils中
public static Subject getSubject() {
Subject subject = ThreadContext.getSubject();
if (subject == null) {
subject = (new Subject.Builder()).buildSubject();
ThreadContext.bind(subject);
}
return subject;
}
Subject$Builder中
public Subject buildSubject() {
return this.securityManager.createSubject(this.subjectContext);
}
此時的securityManager是 DefaultSecurityManager
public Subject createSubject(SubjectContext subjectContext) {
//create a copy so we don't modify the argument's backing map:
SubjectContext context = copy(subjectContext);
//ensure that the context has a SecurityManager instance, and if not, add one:
context = ensureSecurityManager(context);
//Resolve an associated Session (usually based on a referenced session ID), and place it in the context before
//sending to the SubjectFactory. The SubjectFactory should not need to know how to acquire sessions as the
//process is often environment specific - better to shield the SF from these details:
context = resolveSession(context);
//Similarly, the SubjectFactory should not require any concept of RememberMe - translate that here first
//if possible before handing off to the SubjectFactory:
context = resolvePrincipals(context);
Subject subject = doCreateSubject(context);
//save this subject for future reference if necessary:
//(this is needed here in case rememberMe principals were resolved and they need to be stored in the
//session, so we don't constantly rehydrate the rememberMe PrincipalCollection on every operation).
//Added in 1.2:
save(subject);
return subject;
}
protected Subject doCreateSubject(SubjectContext context) {
return getSubjectFactory().createSubject(context);
}
屬性SubjectFactory subjectFactory 默認構造方法
public DefaultSecurityManager() {
super();
this.subjectFactory = new DefaultSubjectFactory();
this.subjectDAO = new DefaultSubjectDAO();
}
DefaultSubjectFactory中創建Subject
public Subject createSubject(SubjectContext context) {
SecurityManager securityManager = context.resolveSecurityManager();
Session session = context.resolveSession();
boolean sessionCreationEnabled = context.isSessionCreationEnabled();
PrincipalCollection principals = context.resolvePrincipals();
boolean authenticated = context.resolveAuthenticated();
String host = context.resolveHost();
return new DelegatingSubject(principals, authenticated, host, session, sessionCreationEnabled, securityManager);
}
可見最後Subject中存在很多屬性,在login方法中使用的securityManager, Subject subject = securityManager.login(this, token);
前面登錄過程中的ModularRealmAuthenticator的AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken)方法使用到了屬性 private Collection<Realm> realms;這個屬性是什麼時候設置的
配置文件中爲SecurityManager設置了Realm,
RealmSecurityManager中set方法
public void setRealm(Realm realm) {
if (realm == null) {
throw new IllegalArgumentException("Realm argument cannot be null");
}
Collection<Realm> realms = new ArrayList<Realm>(1);
realms.add(realm);
setRealms(realms);
}
/**
* Sets the realms managed by this <tt>SecurityManager</tt> instance.
*
* @param realms the realms managed by this <tt>SecurityManager</tt> instance.
* @throws IllegalArgumentException if the realms collection is null or empty.
*/
public void setRealms(Collection<Realm> realms) {
if (realms == null) {
throw new IllegalArgumentException("Realms collection argument cannot be null.");
}
if (realms.isEmpty()) {
throw new IllegalArgumentException("Realms collection argument cannot be empty.");
}
this.realms = realms;
afterRealmsSet();
}
protected void afterRealmsSet() {
applyCacheManagerToRealms();
}
其中的afterRealmsSet方法在其子類AuthenticatingSecurityManager中有重寫
protected void afterRealmsSet() {
super.afterRealmsSet();
if (this.authenticator instanceof ModularRealmAuthenticator) {
((ModularRealmAuthenticator) this.authenticator).setRealms(getRealms());
}
}
就是在這裏設置了realms的值
最後配置文件
@Configuration
public class Config {
@Autowired
DataSource dataSource;
@Autowired
OAuth2AuthenticationFilter oAuth2AuthenticationFilter;
@Autowired
OAuth2Realm oAuth2Realm;
/* public @Bean Factory<org.apache.shiro.mgt.SecurityManager> factory(){
return new IniSecurityManagerFactory("classpath:shiro.ini");
}*/
public @Bean org.apache.shiro.cache.MemoryConstrainedCacheManager cacheManager(){
return new MemoryConstrainedCacheManager();
}
public @Bean org.apache.shiro.mgt.SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
Collection<Realm> realms = new ArrayList<Realm>();
//oAuth2Realm.setAuthenticationTokenClass(OAuth2Token.class);
//realms.add(oAuth2Realm);
realms.add(this.jdbcRealm());
securityManager.setRealms(realms );
securityManager.setCacheManager(cacheManager());
return securityManager;
}
public @Bean JdbcRealm jdbcRealm(){
JdbcRealm jdbcRealm = new JdbcRealm();
jdbcRealm.setDataSource(dataSource);
return jdbcRealm;
}
public @Bean org.apache.shiro.spring.web.ShiroFilterFactoryBean shiroFilter(){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager());
shiroFilterFactoryBean.setUnauthorizedUrl("/");
shiroFilterFactoryBean.setLoginUrl("/");
Map<String, String> filterChainDefinitionMap = new HashMap<String, String>();
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/authorize", "anon");
filterChainDefinitionMap.put("/accessToken", "anon");
filterChainDefinitionMap.put("/userInfo", "anon");
filterChainDefinitionMap.put("/oauth2Failure.jsp", "anon");
filterChainDefinitionMap.put("/oauth2/client/login", "oAuth2AuthenticationFilter");
filterChainDefinitionMap.put("/yes/*", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap );
Map<String, Filter> filters = new HashMap<String, Filter>();
filters.put("oAuth2AuthenticationFilter", oAuth2AuthenticationFilter);
shiroFilterFactoryBean.setFilters(filters );
return shiroFilterFactoryBean;
}
/*public @Bean org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor advisor(){
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager());
return advisor;
}*/
/*public @Bean org.springframework.web.servlet.handler.SimpleMappingExceptionResolver smer(){
SimpleMappingExceptionResolver smer = new SimpleMappingExceptionResolver();
Properties mappings = new Properties();
mappings.setProperty("org.apache.shiro.authz.UnauthorizedException", "/no/noqx.jsp");
mappings.setProperty("org.apache.shiro.authz.UnauthenticatedException", "/no/nosf.jsp");
smer.setExceptionMappings(mappings);
return smer;
}*/
public @Bean org.springframework.web.servlet.view.InternalResourceViewResolver irvr(){
InternalResourceViewResolver irvr = new InternalResourceViewResolver();
irvr.setPrefix("/");
irvr.setSuffix(".jsp");
return irvr;
}