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方法,
还是把配置文件的名称该了就好。