Shiro 2 Subject的创建

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 realms; 这个属性是什么时候设置的
配置文件中为SecurityManager设置了Realm,


RealmSecurityManager中set方法

public void setRealm(Realm realm) { if (realm == null) { throw new IllegalArgumentException("Realm argument cannot be null"); } Collection realms = new ArrayList(1); realms.add(realm); setRealms(realms); }/** * Sets the realms managed by this SecurityManager instance. * * @param realms the realms managed by this SecurityManager instance. * @throws IllegalArgumentException if the realms collection is null or empty. */ public void setRealms(Collection 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 @BeanFactory factory(){ return newIniSecurityManagerFactory("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 realms = new ArrayList(); //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 filterChainDefinitionMap = new HashMap(); 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 filters = new HashMap(); filters.put("oAuth2AuthenticationFilter", oAuth2AuthenticationFilter); shiroFilterFactoryBean.setFilters(filters ); return shiroFilterFactoryBean; } /*public @Bean org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor advisor(){ AuthorizationAttributeSourceAdvisoradvisor = 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; }



【Shiro 2 Subject的创建】

    推荐阅读