shiro学习之路(3)----自定义Realm

来源:互联网 发布:unity3d 人物移动跳跃 编辑:程序博客网 时间:2024/05/29 19:28

1.前面我们讲到shiro对数据的操作主要是通过Realm来进行,但是默认的Realm有个很大的不好之处,

   就是表名,字段名规定死了,不灵活,所以今天我们就自定义Realm,这样就可以根据自己设置的表名

   字段名来进行操作


2.首页定义一个实体


3.定义一个Dao,里面主要包含三个方法,根据用户名查找用户,根据用户名查找该用户所用的角色,根据用户名查找该用户角色所拥有的权限

   2,3两个方法这里不做讲,是做权限验证与授权管理,在后面会做介绍


package com.spf.utils;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.util.HashSet;import java.util.Set;/** * @Auther SPF */public class UserDao {    //根据用户名查找用户    public User getByUsername(Connection conn, String username) throws Exception {        User resultUser = null;        String sql = "select * from user where username=?";        PreparedStatement ps = conn.prepareStatement(sql);        ps.setString(1, username);        ResultSet rs = ps.executeQuery();        if(rs.next()) {            resultUser = new User();            resultUser.setId(rs.getInt("id"));            resultUser.setUsername(rs.getString("username"));            resultUser.setPassword(rs.getString("password"));        }        return resultUser;    }    //根据用户名查找改用户所拥有的角色    public Set<String> getRoles(Connection conn, String username) throws Exception {        Set<String> roles = new HashSet<String>();        String sql = "select * from t_user u, t_role r where u.role_id=r.id and u.username=?";        PreparedStatement ps = conn.prepareStatement(sql);        ps.setString(1, username);        ResultSet rs = ps.executeQuery();        while(rs.next()) {            roles.add(rs.getString("rolename"));        }        return roles;    }    //根据用户名查找该用户角色所拥有的权限    public Set<String> getPerms(Connection conn, String username) throws Exception {        Set<String> perms = new HashSet<String>();        String sql = "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=?";        PreparedStatement ps = conn.prepareStatement(sql);        ps.setString(1, username);        ResultSet rs = ps.executeQuery();        while(rs.next()) {            perms.add(rs.getString("permissionname"));        }        return perms;    }}

4.定义一个自己的Realm


package com.spf.utils;import org.apache.shiro.authc.*;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;/** 自定义Reaml * @Auther SPF */public class MyRealm extends AuthorizingRealm {    private UserDao userDao = new UserDao();    // 为当前登陆成功的用户授予权限和角色,已经登陆成功了    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {            String username = (String) principals.getPrimaryPrincipal(); //获取用户名            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();            Connection conn = null;            try {                conn = getConnection();                authorizationInfo.setRoles(userDao.getRoles(conn, username)); //设置角色                authorizationInfo.setStringPermissions(userDao.getPerms(conn, username)); //设置权限            } catch (Exception e) {                e.printStackTrace();            } finally {                try {                    conn.close();                } catch (Exception e) {                    e.printStackTrace();                }            }            return authorizationInfo;    }    // 验证当前登录的用户,获取认证信息    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {            String username = (String) token.getPrincipal(); // 获取用户名            Connection conn = null;            try {                conn = getConnection();                User user = userDao.getByUsername(conn, username); // 仅仅是根据用户名查出的用户信息,不涉及到密码                if (user != null) {                    AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(                            user.getUsername(), user.getPassword(), "myrealm");                    return authcInfo;                } else {                    throw new UnknownAccountException("No account found for user [" + username + "] 用户不存在");                }            } catch (Exception e) {                e.printStackTrace();            } finally {                try {                    conn.close();                } catch (Exception e) {                    e.printStackTrace();                }            }            return null;    }    /**     * 链接数据库     * @return     */    private Connection getConnection() {        String url = "jdbc:mysql:///test";        String name = "root";        String pwd = "SPF940805.";        Connection conn = null;        try {            conn = DriverManager.getConnection(url,name,pwd);        } catch (SQLException e) {            e.printStackTrace();        }        return conn;    }}

5.修改我们的.ini文件



就是把中间连数据库的数据源删掉,第一行的jdbcRealm路径改为自己的路径就好了


6.修改main方法,

还是把配置文件的名称该了就好。