主题是Shiro中十分重要的对象,可以简单的理解为“当前用户”。首先来看下主题的继承关系
不论是网络应用程序还是普通应用程序,我们在某个方法里面都已通过以下方法来获取主题对象并使用会话
<代码>主题currentUser=org.apache.shiro.SecurityUtils.getSubject (); 如果(! currentUser.isAuthenticated ()) { UsernamePasswordToken牌=new UsernamePasswordToken(“用户”,“密码”); token.setRememberMe(真正的); 尝试{ currentUser。登录(令牌); 会议会话=currentUser.getSession (); 会话。setAttribute(“关键”、“价值”); }捕捉(UnknownAccountException阿联酋){//用户不存在 }捕捉(IncorrectCredentialsException冰){//密码错误 }捕捉(LockedAccountException莱城){//用户被锁 }捕捉(AuthenticationException ae) {//意想不到的状况——错误吗? } }代码>
该SecurityUtils位于shiro-core.jar中
简单的两句代码就可以完成登录验证,也可以使用会话,看起来十分简单,可简单的背后可能又隐藏着许多复杂之处,接下来我们就来一探究竟。
<代码>/* * *访问当前访问{@code主题}调用代码根据alt=" Apache Shiro源码解读之主题的创建"><代码>公共类ShiroFilter延伸AbstractShiroFilter { @Override 公共空间init()抛出异常{ WebEnvironment env=WebUtils.getRequiredWebEnvironment (getServletContext ()); setSecurityManager (env.getWebSecurityManager ()); FilterChainResolver解析器=env.getFilterChainResolver (); 如果(解析器!=null) { setFilterChainResolver(解析器); } } }代码>在这里之看到了初始化方法,看名字应该是初始化给过滤器时候运行的,那么在何处调用的,我们继续看看他的父类
<代码>公共抽象类AbstractFilter延伸ServletContextSupport实现滤波器{ FilterConfig FilterConfig公共最后空白init()抛出ServletException { filterConfig setFilterConfig (); 尝试{ alt=" Apache Shiro源码解读之主题的创建">HTTP请求处理过程
1,每个HTTP请求都被ShoriFilter拦截进行处理
2,将SecurityManager对象和包装后的请求和响应作为构造参数创建WebSubject.Builder实例,并调用buildWebSubject方法创建主题
3,在构造方法中创新新的SubjectContext实例,并将SecurityManager保存到SubjectContext实例中
4,将请求和响应也添加到SubjectContext中保存
5,将SubjectContext作为参数,调用SecurityManager的createSubject方法创建主题对象
6,将SubjectContext作为参数,调用SubjectFactory【DefaultSubjectFactory】的createSubject方法创建主题
7,接着取出SubjectContext一路收集来的数据来构建DelegatingSubject对象并返回。
8,当调用主题的getSession方法的时候,如果会话不存在,则首先创建一个新的DefaultSessionContext实例并设置主机值【可能是空】
9日将sessionContext对象作为参数调用SecurityManager的开始方法来创建会话
10,从sessionContext中取出HttpServletRequest,并调用HttpServletRequest的getSession方法来获取HttpSession,同时从sessionContext中取出主机,使用这两个值作为构造函数的参数实例化HttpServletSession类。
11日到此,会话的创建过程结束,此时的HttpServletSession纯粹只是HttpSession的代理一样。Apache Shiro源码解读之主题的创建