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
配置文件中为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的创建】
推荐阅读
- Shiro之保存Session到数据库中-yellowcong
- √|shiro教程(session管理)
- Shiro入门-session管理
- servlet总结|设置session失效时间(不使用框架)----使用shiro设置session失效时间(使用shiro框架)
- shiro|shiro中session实现的简单分析
- Shiro 设置session超时时间
- springboot+shiro入门学习(一)
- Shiro|shiro中的session 获取过期时间/设置过期时间
- Shiro 之Subject、SecurityManager、Realm源码分析
- spring+shiro 整合之自己注册会话和自写realm