【Shiro】Apache Shiro架构之自定义realm

来源:互联网 发布:零食店铺推荐知乎 编辑:程序博客网 时间:2024/05/22 09:51

之前写的博客里都是使用.ini文件来获取信息的,包括用户信息,角色信息,权限信息等。进入系统时,都是从.ini文件这读取进入的。实际中除非这个系统特别特别简单,否则一般都不是这样干的,这些信息都是需要在数据库中进行维护的,所以就需要用到自定义realm了。

写在前面:这篇博文是基于上一篇Shiro集成web基础之上修改的。

1. 数据库建表

  首先在数据库中新建三个表:t_user,t_role和t_permission,分别存储用户信息,角色信息和权限信息,建表语句如下:

<code class="language-sql hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-operator" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">CREATE</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">TABLE</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`t_role`</span> (  <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`id`</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NOT</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NULL</span> AUTO_INCREMENT COMMENT <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'主键'</span>,  <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`rolename`</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">varchar</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">DEFAULT</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NULL</span> COMMENT <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'角色名称'</span>,  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">PRIMARY</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">KEY</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`id`</span>)) ENGINE=InnoDB AUTO_INCREMENT=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">DEFAULT</span> CHARSET=utf8<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">CREATE</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">TABLE</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`t_user`</span> (  <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`id`</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NOT</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NULL</span> AUTO_INCREMENT COMMENT <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'用户主键'</span>,  <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`username`</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">varchar</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NOT</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NULL</span> COMMENT <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'用户名'</span>,  <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`password`</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">varchar</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NOT</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NULL</span> COMMENT <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'密码'</span>,  <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`role_id`</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">DEFAULT</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NULL</span> COMMENT <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'外键关联role表'</span>,  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">PRIMARY</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">KEY</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`id`</span>),  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">KEY</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`role_id`</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`role_id`</span>),  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">CONSTRAINT</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`t_user_ibfk_1`</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">FOREIGN</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">KEY</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`role_id`</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">REFERENCES</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`t_role`</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`id`</span>)) ENGINE=InnoDB AUTO_INCREMENT=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">DEFAULT</span> CHARSET=utf8<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">CREATE</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">TABLE</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`t_permission`</span> (  <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`id`</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NOT</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NULL</span> AUTO_INCREMENT COMMENT <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'主键'</span>,  <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`permissionname`</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">varchar</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">50</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NOT</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NULL</span> COMMENT <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'权限名'</span>,  <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`role_id`</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">DEFAULT</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">NULL</span> COMMENT <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'外键关联role'</span>,  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">PRIMARY</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">KEY</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`id`</span>),  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">KEY</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`role_id`</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`role_id`</span>),  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">CONSTRAINT</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`t_permission_ibfk_1`</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">FOREIGN</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">KEY</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`role_id`</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">REFERENCES</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`t_role`</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">`id`</span>)) ENGINE=InnoDB AUTO_INCREMENT=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">DEFAULT</span> CHARSET=utf8</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul>

  每个表中我添加了一些测试数据,如下: 
user

role

permission

2. 自定义realm

  自定义realm中需要操作数据库,所有首先得先写一个dao,使用的是原始的jdbc,主要是下面的自定义realm。

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">UserDao</span> {</span>    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//根据用户名查找用户</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> User <span class="hljs-title" style="box-sizing: border-box;">getByUsername</span>(Connection conn, String username) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception {        User resultUser = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;        String sql = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"select * from t_user where username=?"</span>;        PreparedStatement ps = conn.prepareStatement(sql);        ps.setString(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, username);        ResultSet rs = ps.executeQuery();        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(rs.next()) {            resultUser = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> User();            resultUser.setId(rs.getInt(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"id"</span>));            resultUser.setUsername(rs.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"username"</span>));            resultUser.setPassword(rs.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"password"</span>));        }        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> resultUser;    }    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//根据用户名查找改用户所拥有的角色</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Set<String> <span class="hljs-title" style="box-sizing: border-box;">getRoles</span>(Connection conn, String username) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception {        Set<String> roles = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> HashSet<String>();        String sql = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"select * from t_user u, t_role r where u.role_id=r.id and u.username=?"</span>;        PreparedStatement ps = conn.prepareStatement(sql);        ps.setString(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, username);        ResultSet rs = ps.executeQuery();        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span>(rs.next()) {            roles.add(rs.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"rolename"</span>));        }        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> roles;    }    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//根据用户名查找该用户角色所拥有的权限</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Set<String> <span class="hljs-title" style="box-sizing: border-box;">getPerms</span>(Connection conn, String username) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Exception {        Set<String> perms = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> HashSet<String>();        String sql = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"select * from t_user u, t_role r, t_permission p where u.role_id=r.id and p.role_id=r.id and u.username=?"</span>;        PreparedStatement ps = conn.prepareStatement(sql);        ps.setString(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, username);        ResultSet rs = ps.executeQuery();        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span>(rs.next()) {            perms.add(rs.getString(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"permissionname"</span>));        }        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> perms;    }}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li></ul>

  有了dao了,接下来就可以写自定义的realm了,自定义realm需要继承AuthorizingRealm类,因为该类封装了很多方法,它也是一步步继承自Realm类的,继承了AuthorizingRealm类后,需要重写两个方法:

doGetAuthenticationInfo()方法:用来验证当前登录的用户,获取认证信息 
doGetAuthorizationInfo()方法:用来为当前登陆成功的用户授予权限和角色(已经登陆成功了)

  下面来看一下具体的实现:

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MyRealm</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">AuthorizingRealm</span> {</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> UserDao userDao = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> UserDao();    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 为当前登陆成功的用户授予权限和角色,已经登陆成功了</span>    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> AuthorizationInfo <span class="hljs-title" style="box-sizing: border-box;">doGetAuthorizationInfo</span>(            PrincipalCollection principals) {        String username = (String) principals.getPrimaryPrincipal(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//获取用户名</span>        SimpleAuthorizationInfo authorizationInfo = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SimpleAuthorizationInfo();        Connection conn = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {            conn = DbUtil.getConnection();            authorizationInfo.setRoles(userDao.getRoles(conn, username)); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置角色</span>            authorizationInfo.setStringPermissions(userDao.getPerms(conn, username)); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//设置权限            </span>        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) {            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// TODO Auto-generated catch block</span>            e.printStackTrace();        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">finally</span> {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {                DbUtil.closeConnection(conn);            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) {                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// TODO Auto-generated catch block</span>                e.printStackTrace();            }        }        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> authorizationInfo;    }    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 验证当前登录的用户,获取认证信息</span>    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> AuthenticationInfo <span class="hljs-title" style="box-sizing: border-box;">doGetAuthenticationInfo</span>(            AuthenticationToken token) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> AuthenticationException {        String username = (String) token.getPrincipal(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 获取用户名</span>        Connection conn = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {            conn = DbUtil.getConnection();            User user = userDao.getByUsername(conn, username); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 仅仅是根据用户名查出的用户信息,不涉及到密码</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (user != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {                AuthenticationInfo authcInfo = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SimpleAuthenticationInfo(                        user.getUsername(), user.getPassword(), <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"myrealm"</span>);                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> authcInfo;            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;            }        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) {            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// TODO Auto-generated catch block</span>            e.printStackTrace();        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">finally</span> {            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {                DbUtil.closeConnection(conn);            } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) {                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// TODO Auto-generated catch block</span>                e.printStackTrace();            }        }        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;    }}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li></ul>

  从上面两个方法中可以看出:验证身份的时候是根据用户输入的用户名先从数据库中查出该用户名对应的用户,这时候并没有涉及到密码,也就是说到这一步的时候,即使用户输入的密码不对,也是可以查出来该用户的,然后将该用户的正确信息封装到authcInfo 中返回给Shiro,接下来就是Shiro的事了,它会根据这里面的真实信息与用户前台输入的用户名和密码进行校验, 这个时候也要校验密码了,如果校验通过就让用户登录,否则跳转到指定页面。同理,权限验证的时候也是先根据用户名获取与该用户名有关的角色和权限,然后封装到authorizationInfo中返回给Shiro。

3. 修改ini文件

  在该配置文件中,[users]和[roles]的信息就可以删掉了,因为这些信息都是从数据库中维护的,另外还要在文件中指定我们自定义的realm的完全限定名,并且指定securityManager的realm使用我们自定义的realm,如下:

<code class="language-ini hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-title" style="box-sizing: border-box;">[main]</span>authc.loginUrl=/loginroles.unauthorizedUrl=/unauthorized.jspperms.unauthorizedUrl=/unauthorized.jsp#定义自己的realm<span class="hljs-setting" style="box-sizing: border-box;">myRealm=<span class="hljs-value" style="box-sizing: border-box;">demo.shiro.realm.MyRealm</span></span>securityManager.realms=$myRealm#定义请求的地址需要做什么验证<span class="hljs-title" style="box-sizing: border-box;">[urls]</span>/login=anon /admin=authc /student=roles<span class="hljs-title" style="box-sizing: border-box;">[teacher]</span>/teacher=perms<span class="hljs-title" style="box-sizing: border-box;">["user:create"]</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li></ul>

  这样我们自定义的realm就搞定了,根据配置文件,当我们请求…/admin的时候会进行身份认证,所以会进入LoginServlet中,当调用currentUser.login(token);的时候,就会进入我们自定义的realm中的doGetAuthenticationInfo方法进行身份初始化,然后交给Shiro去验证。当我们请求…./student的时候,也会先进行身份验证,就是上面的过程,然后验证通过,当我们再次请求…/student的时候,就会进入我们自定义的realm中的doGetAuthorizationInfo方法进行权限的初始化,然后交给Shiro去验证。 
  下一篇博文我将总结一下如何将Shiro运用到实际项目中,即如何将Shiro整合到Spring中。


—–乐于分享,共同进步! 
—–我的博客主页:http://blog.csdn.net/eson_15

0 0