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<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;
	}
	



發佈了68 篇原創文章 · 獲贊 9 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章