`

Shiro自定义Realm

阅读更多
1. Shiro自定义Realm

create maven project -->
maven-archetype-webapp -->
    GroupId: com.andrew.shiro
    Artifact Id: ShiroRealm
    Package: com.andrew.shiro

jdk版本修改为1.8


create table t_role (
  id int(11) not null  auto_increment,
  rolename varchar(20) default null,
  primary key (id)
) engine=innodb auto_increment=0 default charset=utf8;
insert into t_role(id,roleName) values(1,'admin');
insert into t_role(id,roleName) values(2,'teacher');

create table t_permission (
    id int(11) not null auto_increment,
    permissionname varchar(50) default null,
    roleid int(11) default null,
    primary key (id),
    constraint t_permission_ibfk_1 foreign key (roleid) references t_role (id)
) engine=innodb auto_increment=0 default charset=utf8;
insert into t_permission(id, permissionName, roleId) values(1,'user:*',1);
insert into t_permission(id, permissionName, roleId) values(2,'student:*',2);


CREATE TABLE t_user (
  id int(11) NOT NULL AUTO_INCREMENT,
  userName varchar(20) DEFAULT NULL,
  password varchar(20) DEFAULT NULL,
  roleId int(11) DEFAULT NULL,
  PRIMARY KEY (id),
  KEY roleId (roleId),
  CONSTRAINT t_user_ibfk_1 FOREIGN KEY (roleId) REFERENCES t_role (id)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
insert into t_user(id,userName,password,roleId) values (1,'andrew','123456',1);
insert into t_user(id,userName,password,roleId) values (2,'jack','123',2);
insert into t_user(id,userName,password,roleId) values (3,'marry','234',NULL);
insert into t_user(id,userName,password,roleId) values (4,'json','345',NULL);

CREATE TABLE users (
  id int(11) NOT NULL AUTO_INCREMENT,
  userName varchar(20) DEFAULT NULL,
  password varchar(20) DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
insert into users(id,userName,password) values (1,'java1234','123456');

src/main/java/com/andrew/dao/UserDao.java

package com.andrew.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashSet;
import java.util.Set;
import com.andrew.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;
    }
}

src/main/java/com/andrew/User.java

package com.andrew.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;
    }
}

src/main/java/com/andrew/MyRealm.java

package com.andrew.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.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.andrew.dao.UserDao;
import com.andrew.entity.User;
import com.andrew.util.DbUtil;
public class MyRealm extends AuthorizingRealm {
    private UserDao userDao = new UserDao();
    private DbUtil dbUtil = new DbUtil();
    /**
     * 为当前登录的用户授予角色和权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String userName = (String) principals.getPrimaryPrincipal();
        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) {
                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) {
                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) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

src/main/java/com/andrew/AdminServlet.java

package com.andrew.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class AdminServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("admin do get");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("admin do post");
    }
}

src/main/java/com/andrew/LoginServlet.java

package com.andrew.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("login doget");
        req.getRequestDispatcher("login.jsp").forward(req, resp);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("login dopost");
        String userName = req.getParameter("userName");
        String password = req.getParameter("password");
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
        try {
            subject.login(token);
            resp.sendRedirect("success.jsp");
        } catch (Exception e) {
            e.printStackTrace();
            req.setAttribute("errorInfo", "用户名或者密码错误");
            req.getRequestDispatcher("login.jsp").forward(req, resp);
        }
    }
}

src/main/java/com/andrew/DbUtil.java

package com.andrew.util;
import java.sql.Connection;
import java.sql.DriverManager;
/**
 * 数据库工具类
 */
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/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) {
            e.printStackTrace();
            System.out.println("数据库连接失败");
        }
    }
}

src/main/resources/log4j.properties

log4j.rootLogger=DEBUG, Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

src/main/webapp/WEB-INF/shiro.ini

[main]
authc.loginUrl=/login
roles.unauthorizedUrl=/unauthorized.jsp
perms.unauthorizedUrl=/unauthorized.jsp
myRealm=com.andrew.realm.MyRealm
securityManager.realms=$myRealm
[urls]
/login=anon
/admin*=authc
/student=roles[teacher]
/teacher=perms["user:create"]

src/main/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>ShrioWeb</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
    <!-- 添加shiro支持 -->
    <listener>
        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
    </listener>
    <filter>
        <filter-name>ShiroFilter</filter-name>
        <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ShiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <servlet>
        <servlet-name>loginServlet</servlet-name>
        <servlet-class>com.andrew.servlet.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>loginServlet</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>adminServlet</servlet-name>
        <servlet-class>com.andrew.servlet.AdminServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>adminServlet</servlet-name>
        <url-pattern>/admin</url-pattern>
    </servlet-mapping>
</web-app>

src/main/webapp/index.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
hello World!
</body>
</html>

src/main/webapp/login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="login" method="post">
    userName:<input type="text" name="userName"/><br/>
    password:<input type="password" name="password"/><br/>
    <input type="submit" value="登录"/>
</form>
</body>
</html>

src/main/webapp/success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
${info }
欢迎你!
<shiro:hasRole name="admin">
    欢迎有admin角色的用户!<shiro:principal/>
</shiro:hasRole>
<shiro:hasPermission name="student:create">
    欢迎有student:create权限的用户!<shiro:principal/>
</shiro:hasPermission>
</body>
</html>

src/main/webapp/unauthorized.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
认证未通过,或者权限不足
</body>
</html>

http://localhost:8080/ShiroRealm/admin
跳转到:
http://localhost:8080/ShiroRealm/login;jsessionid=63F5880F36DD0DA79A90D10CAEC29CEA
andrew 123456 login
欢迎你! 欢迎有admin角色的用户! 欢迎有student:create权限的用户!
分享到:
评论

相关推荐

    从实例入手学习Shiro自定义Realm实现查询数据进行验证示例代码.zip

    本实例将通过自定义Realm来演示如何使用Shiro从数据库中查询数据进行用户验证。 首先,我们需要了解 Realm 的基本概念。在Shiro中, Realm 是一个接口,它实现了认证和授权的功能。默认的 Realm 类型包括 JdbcRealm...

    Spring配置shiro时自定义Realm中属性无法使用注解注入的解决办法

    在Spring集成Shiro进行安全控制时,我们常常需要自定义Realm来实现权限验证与授权功能。然而,在实际操作中,可能会遇到一个问题:当我们在自定义的Realm类中使用注解(@Autowired)尝试注入Spring管理的Bean时,这些...

    shiro-realm案例

    在"shiro-realm案例"中,我们将探讨如何自定义Realm来实现与应用程序特定的权限验证。 Realm在Shiro中扮演着核心角色,它是身份验证(Authentication)和授权(Authorization)的基础。 Realm可以看作是Shiro与...

    shiro权限框架自定义Realm示例

    在这个“shiro权限框架自定义Realm示例”中,我们将深入理解Shiro的核心组件Realm以及如何根据实际需求对其进行定制。 Realm在Shiro中扮演着关键角色,它是Shiro与应用程序特定的安全数据源(如数据库、LDAP或文件...

    用于测试shiro中自定义Realm的测试代码

    在这个名为“用于测试shiro中自定义Realm的测试代码”的项目中,我们主要关注的是如何自定义Realm来适应特定的认证和授权需求。 Realm在Shiro中扮演着核心角色,它是Shiro与应用程序特定的安全存储(如数据库、...

    shiro web中自定义Realm

    在Web应用中,自定义Realm是为了适配具体的应用场景,因为Shiro的默认Realm并不能满足所有需求。自定义Realm可以让我们更好地控制认证和授权的过程,以满足业务逻辑。以下将详细介绍如何在Shiro中创建自定义Realm。 ...

    SpringBoot 、Shiro、 自定义注解权限控制源码下载

    3. **Shiro的集成**:研究如何在SpringBoot应用中配置Shiro,包括安全配置、 Realm(认证和授权信息提供者)的实现以及自定义注解的编写和使用。 4. **Shiro的权限控制**:掌握如何使用Shiro的注解进行权限判断,如@...

    spring boot 集成 shiro 自定义密码验证 自定义freemarker标签根据权限渲染不同页面(推荐

    然后,需要创建一个自定义的 Realm,用于查询用户信息和权限信息,并将其缓存到 Shiro 的 Session 中: ```java @Component public class MyShiroRealm extends AuthorizingRealm { private Logger log = ...

    Shiro Realm 权限的验证流程和缓存机制.docx

    当我们需要自定义权限验证时,通常会创建多个 Realm 类,每个类继承自 `AuthorizingRealm`。 权限验证流程: 当用户尝试访问受保护的资源时,Shiro 会按照在 Spring Boot 配置中定义 Realm Bean 的顺序进行权限验证...

    shiro授权 shiro和企业项目整合开发

    在本文中,我们将深入探讨 Shiro 的授权机制,以及如何在实际的企业项目中与之整合,实现自定义 Realm,缓存管理和验证码与“记住我”功能。 ### 一、Shiro 授权机制 Shiro 的授权(Authorization)主要负责确定...

    shiro第六章Realm完整Demo

    例如,我们可以创建一个自定义的 Realm 类,继承自`AuthorizingRealm`,然后在配置文件中指定这个 Realm。 4. **Demo实现步骤**: - 创建 Realm 类:实现 `AuthorizingRealm` 接口,并重写`...

    shiro demo 实例 jdbcRealm

    shiro demo 源码里面2中realm 一种是jdbcRealm 一种是自定义realm 有sql脚本。请看db文件夹下的readme.txt 有关这个项目的详细介绍,使用了简单的标签库权限控制当做例子

    shiro源码分析(四)具体的Realm

    Apache Shiro是一个强大的Java安全框架,...通过自定义 Realm,开发者可以将Shiro与任何数据源集成,实现灵活、可扩展的安全管理。对Shiro源码的深入理解和分析有助于我们更好地利用这个框架,提高应用的安全性和性能。

    shiro_tool.zip

    如果包含自定义Realm,那可能是为了连接特定数据库或其他数据源进行用户验证。 学习和使用Shiro,你可以了解如何创建安全的登录系统,如何实现基于角色的权限控制,以及如何管理用户会话。此外,熟悉Shiro的事件...

    shiro整合ssmDemo可直接运行

    在提供的"shiro_4"压缩包中,可能包含了完整的SSM项目源码,包括Shiro的配置文件、自定义Realm的实现、以及相关业务代码。通过分析这些代码,你可以更好地理解Shiro如何与SSM整合,以及其在实际项目中的应用。 ### ...

    基于springboot的shiro完整项目案例

    自定义Realm允许开发者将Shiro与自己的用户数据库或其他认证源对接。在项目案例中,这个自定义 Realm 可能会连接到MySQL、Oracle等数据库,进行用户和角色的查询。 **SecurityManager** SecurityManager是Shiro的...

    shiro_demo.rar

    3. 自定义Realm:Shiro通过 Realm 连接实际的数据源进行认证和授权,我们需要创建一个自定义的Realm类,继承AuthorizingRealm,实现doGetAuthenticationInfo和doGetAuthorizationInfo方法。 4. 配置Filter:在Web...

    shiro的全流程demo,世界shiro在spring中认证、授权流程,自定义授权类型,分布式session、授权缓存的实现

    本项目是一个基于 Spring Boot 的 Shiro 全流程示例,涵盖了从用户登录认证到权限控制的完整流程,并实现了自定义授权类型、分布式 session 和授权缓存。 首先,我们来看 Shiro 的认证过程。在 Spring Boot 应用中...

    单机版的shiro

    Realm 是 Shiro 和应用安全数据源之间的桥梁,你可以自定义 Realm 类来连接 Mybatis 并执行 SQL 查询,以获取用户信息和角色权限。 **3. Redis 作为缓存** Redis 是一个高性能的键值数据库,常用于缓存数据以提高...

    shior2.zip

    本案例“shior2.zip”就是关于SpringBoot与Shiro整合的一个实例,主要涉及了如何利用MyBatis Plus进行数据库操作,以及Shiro如何自定义Realm以实现权限认证。 首先,SpringBoot与Shiro的整合允许开发者快速构建具有...

Global site tag (gtag.js) - Google Analytics