java安全框架-Shiro学习笔记(七)-自定义realm

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-31 19:38   879   0
这一小节,我们将使用数据库中的数据,并自定义realm的形式,进行身份和权限的认证。
那我们依旧采用上节中用到的ShiroWeb项目
第一步:创建数据库的结构:
第二步:在pom.xml中添加mysql的驱动包
 <dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.37</version>
 </dependency>
第三步:在项目中添加工具类,用于创建数据库连接,关闭数据库连接。
package com.java1234.util;

import java.sql.Connection;
import java.sql.DriverManager;

/**
 * 数据库工具类
 * @author 
 *
 */
public class DbUtil {

 /**
  * 获取数据库连接
  * @return
  * @throws Exception
  */
 public Connection getCon() throws Exception{
  Class.forName("com.mysql.jdbc.Driver");
  Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/db_shiro", "root", "root");
  return con;
 }
 
 /**
  * 关闭数据库连接
  * @param con
  * @throws Exception
  */
 public void closeCon(Connection con)throws Exception{
  if(con!=null){
   con.close();
  }
 }
 
 public static void main(String[] args) {
  DbUtil dbUtil=new DbUtil();
  try {
   dbUtil.getCon();
   System.out.println("数据库连接成功");
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   System.out.println("数据库连接失败");
  }
 }
}
第四步:添加entity,用于封装数据库的数据信息,添加dao层,用于数据库的查询。
User.java
package com.java1234.entity;

public class User {

 private Integer id;
 private String userName;
 private String password;
 
 public Integer getId() {
  return id;
 }
 public void setId(Integer id) {
  this.id = id;
 }
 public String getUserName() {
  return userName;
 }
 public void setUserName(String userName) {
  this.userName = userName;
 }
 public String getPassword() {
  return password;
 }
 public void setPassword(String password) {
  this.password = password;
 }
 
 
}
UserDao.java
package com.java1234.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashSet;
import java.util.Set;

import com.java1234.entity.User;

public class UserDao {
 //根据用户名,获取当前登录用户信息进行身份验证
 public User getByUserName(Connection con,String userName)throws Exception{
  User resultUser=null;
  String sql="select * from t_user where userName=?";
  PreparedStatement pstmt=con.prepareStatement(sql);
  pstmt.setString(1, userName);
  ResultSet rs=pstmt.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 con, String userName) throws Exception{
  Set<String> roles=new HashSet<String>();
  String sql="select * from t_user u,t_role r where u.roleId=r.id and u.userName=?";
  PreparedStatement pstmt=con.prepareStatement(sql);
  pstmt.setString(1, userName);
  ResultSet rs=pstmt.executeQuery();
  while(rs.next()){
   roles.add(rs.getString("roleName"));
  }
  return roles;
 }
 //根据用户名,获取当前登录用户全部权限
 public Set<String> getPermissions(Connection con, String userName)throws Exception {
  Set<String> permissions=new HashSet<String>();
  String sql="select * from t_user u,t_role r,t_permission p where u.roleId=r.id and p.roleId=r.id and u.userName=?";
  PreparedStatement pstmt=con.prepareStatement(sql);
  pstmt.setString(1, userName);
  ResultSet rs=pstmt.executeQuery();
  while(rs.next()){
   permissions.add(rs.getString("permissionName"));
  }
  return permissions;
 }
}
第五步:自定义realm,用于身份认证,以及用户身份(角色+权限)授权
package com.java1234.realm;

import java.sql.Connection;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAccount;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
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 com.java1234.dao.UserDao;
import com.java1234.entity.User;
import com.java1234.util.DbUtil;

public class MyRealm extends AuthorizingRealm{
 
 //userDao用于提供数据库数据
 private UserDao userDao=new UserDao();
 //dbUtil创建数据库连接,关闭
 private DbUtil dbUtil=new DbUtil();
 
 /**
  * 为当前登录的用户授予角色和权限
  */
 @Override
 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
  //获取当前用户登录名
  String userName=(String)principals.getPrimaryPrincipal();
  //authorizationInfo存储用户认证信息
  SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
  Connection con=null;
  try{
   con=dbUtil.getCon();
   //为当前用户授予角色
   authorizationInfo.setRoles(userDao.getRoles(con,userName));
   //为当前用户授予权限结合
   authorizationInfo.setStringPermissions(userDao.getPermissions(con,userName));
  }catch(Exception e){
   e.printStackTrace();
  }finally{
   try {
    dbUtil.closeCon(con);
   } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  return authorizationInfo;
 }

 /**
  * 验证当前登录的用户
  */
 @Override
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
  //获取当前用户登录名
  String userName=(String)token.getPrincipal();
  Connection con=null;
  try{
   con=dbUtil.getCon();
   //获取当前用户信息
   User user=userDao.getByUserName(con, userName);
   if(user!=null){
    //该用户的数据库密码,与页面上传递过来的密码信息比较
    //三个参数,用户数据库中的登录名,密码,以及realm的名字(可以随意定义)
    AuthenticationInfo authcInfo=new SimpleAuthenticationInfo(user.getUserName(),user.getPassword(),"xx");
    return authcInfo;
   }else{
    return null;
   }
  }catch(Exception e){
   e.printStackTrace();
  }finally{
   try {
    dbUtil.closeCon(con);
   } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  return null;
 }

}
第六步:通过修改配置文件shiro.ini,向securityManager中注册自定义的realm
[main]
authc.loginUrl=/login
roles.unauthorizedUrl=/unauthorized.jsp
perms.unauthorizedUrl=/unauthorized.jsp
myRealm=com.java1234.realm.MyRealm
securityManager.realms=$myRealm
[urls]
/login=anon
/admin*=authc
/student=roles[teacher]
/teacher=pe硬编码rms["user:create"]
至于之前的[user][roles]等硬编码信息就可以删除了。

测试:
我们用java1234,123456进行登录,通过debug信息监测,授权信息。
通过ctrl+shirft+i(括起来后再使用快捷键:userDao.getRoles(con,userName)),监测到用户拥有的角色信息。

监测到的用户权限信息:


至此身份授权完成。



分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP