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

来源:互联网 发布:八一建军节军装照软件 编辑:程序博客网 时间:2024/04/30 05:11
这一小节,我们将使用数据库中的数据,并自定义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 blocke.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();/** * 为当前登录的用户授予角色和权限 */@Overrideprotected 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 blocke.printStackTrace();}}return authorizationInfo;}/** * 验证当前登录的用户 */@Overrideprotected 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 blocke.printStackTrace();}}return null;}}
第六步:通过修改配置文件shiro.ini,向securityManager中注册自定义的realm
[main]authc.loginUrl=/loginroles.unauthorizedUrl=/unauthorized.jspperms.unauthorizedUrl=/unauthorized.jspmyRealm=com.java1234.realm.MyRealmsecurityManager.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 0
原创粉丝点击