Shiro学习笔记

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。

 

创建一个简单的helloworld

  1. 创建maven工程,jar类型
  2. 添加shiro的jar包

<dependencies>

    <dependency>

        <groupId>org.apache.shiro</groupId>

        <artifactId>shiro-core</artifactId>

        <version>1.2.4</version>

    </dependency>

    <dependency>

        <groupId>org.slf4j</groupId>

        <artifactId>slf4j-log4j12</artifactId>

        <version>1.7.12</version>

        <scope>test</scope>

    </dependency>

</dependencies>

  1. 在src/main/resources下创建

 

log4j.properties直接拷贝其他工程

shiro.ini的配置如下

[users] //说明是用户信息

king=123 //是以键值对出现

wang=1234

  1. 创建HelloWorld.java

import org.apache.shiro.SecurityUtils;

import org.apache.shiro.authc.AuthenticationException;

import org.apache.shiro.authc.UsernamePasswordToken;

import org.apache.shiro.config.IniSecurityManagerFactory;

import org.apache.shiro.mgt.SecurityManager;

import org.apache.shiro.subject.Subject;

import org.apache.shiro.util.Factory;

 

public class HelloWorld {

   

    public static void main(String[] args) {

        //读取配置文件,初始化SecurityManager工厂

        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

        //获取SecurityManager实例

        SecurityManager securityManager = factory.getInstance();

        //SecurityManager实例绑定到SecurityUtils

        SecurityUtils.setSecurityManager(securityManager);

        //获取当前执行的用户

        Subject currentUser = SecurityUtils.getSubject();

        //创建token令牌,用户名/密码

        UsernamePasswordToken token = new UsernamePasswordToken("wang", "1234");

        try {

             //身份验证

            currentUser.login(token);

            System.out.println("身份认证成功!");

        }catch(AuthenticationException e) {

            e.printStackTrace();

            System.out.println("身份认证失败!");

        }

        //退出登录

        currentUser.logout();

    }

}

Subject认证主体

Subject认证主体包含两个信息

Principals:身份,可以是用户名,邮件,手机号码等等,用来标识一个登陆主体身份

Credentials:凭证,常见的有密码,数字证书等等。

Realm & JDBC Realm

Realm:意思是域,shiro从Realm中获取验证数据

Realm有很多种类,例如常见的jdbc realm, jndi realm, text realm(上面那个helloworld用的就是)

测试jdbc_realm使用C3P0连接数据库进行认证

  1. 创建maven工程,jar类型
  2. 在pom.xml文件中添加shiro,C3P0的jar包

<dependencies>

    <dependency>

        <groupId>org.apache.shiro</groupId>

        <artifactId>shiro-core</artifactId>

        <version>1.2.4</version>

    </dependency>

    <dependency>

        <groupId>org.slf4j</groupId>

        <artifactId>slf4j-log4j12</artifactId>

        <version>1.7.12</version>

        <scope>test</scope>

    </dependency>

    <dependency>

        <groupId>c3p0</groupId>

        <artifactId>c3p0</artifactId>

        <version>0.9.1.2</version>

    </dependency>

    <dependency>

        <groupId>commons-logging</groupId>

        <artifactId>commons-logging</artifactId>

        <version>1.2</version>

    </dependency>

    <dependency>

        <groupId>mysql</groupId>

        <artifactId>mysql-connector-java</artifactId>

        <version>5.1.40</version>

    </dependency>

</dependencies>

  1. 在src/main/resources下创建

log4j.properties直接拷贝其他工程

jdbc_realm.ini配置如下

[main]  //如果配置代码需要使用main

jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm   //设置jdbcRealm

dataSource= com.mchange.v2.c3p0.ComboPooledDataSource  //设置数据源

dataSource.driverClass=com.mysql.jdbc.Driver   //driver

dataSource.jdbcUrl=jdbc:mysql://localhost:3306/mydata?characterEncoding=UTF-8&useSSL=true //url

dataSource.user=root  //用户名

dataSource.password=123 //密码

 

jdbcRealm.dataSource=$dataSource   //相当于jdbcRealm.setDataSource(dataSource)

securityManager.realms=$jdbcRealm  //相当于securityManager.setRealms(jdbcRealm)

 

创建一个数据库mydata , 创建一个数据表,表名为固定名称users,

字段为userName,password,如果名称不同则jdbcRealm会找不到指定的表名和字段名进行比对

编写测试类

import org.apache.shiro.SecurityUtils;

import org.apache.shiro.authc.AuthenticationException;

import org.apache.shiro.authc.UsernamePasswordToken;

import org.apache.shiro.config.IniSecurityManagerFactory;

import org.apache.shiro.mgt.SecurityManager;

import org.apache.shiro.subject.Subject;

import org.apache.shiro.util.Factory;

 

public class HelloWorld {

   

    public static void main(String[] args) {

        //读取配置文件,初始化SecurityManager工厂

        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:jdbc_realm.ini");

        //获取SecurityManager实例

        SecurityManager securityManager = factory.getInstance();

        //SecurityManager实例绑定到SecurityUtils

        SecurityUtils.setSecurityManager(securityManager);

        //获取当前执行的用户

        Subject currentUser = SecurityUtils.getSubject();

        //创建token令牌,用户名/密码

        UsernamePasswordToken token = new UsernamePasswordToken("wang", "12345");

        try {

            //身份验证

            currentUser.login(token);

            System.out.println("身份认证成功!");

        }catch(AuthenticationException e) {

            e.printStackTrace();

            System.out.println("身份认证失败!");

        }

        //退出登录

        currentUser.logout();

    }

 

}

 

权限认证核心要素

权限认证,也就是访问控制,即在应用中控制谁能访问哪些资源

在权限认证中,最核心的三个要素是:权限,角色,用户

权限:操作资源的权利,比如访问某个页面,以及对某个模块的数据的添加,修改,删除,查看的权利

角色:是权利的集合,一种角色可以包含多种权限

用户:在shiro中,代表访问系统的用户成为Subject

测试角色

在src/main/resources下创建shiro_role.ini配置文件

[users]

wang=12345,role3,role2

zhangsan=12345,role1

 

说明:用户名wang,密码:12345,拥有角色role3,role2

创建shiro工具类,用于判断身份是否合法

import org.apache.shiro.SecurityUtils;

import org.apache.shiro.authc.AuthenticationException;

import org.apache.shiro.authc.UsernamePasswordToken;

import org.apache.shiro.config.IniSecurityManagerFactory;

import org.apache.shiro.mgt.SecurityManager;

import org.apache.shiro.subject.Subject;

import org.apache.shiro.util.Factory;

 

public class ShiroUtils {

 

    public static Subject login(String configFile, String userName, String password) {

        // 读取配置文件,初始化SecurityManager工厂

        Factory<SecurityManager> factory = new IniSecurityManagerFactory(configFile);

        // 获取SecurityManager实例

        SecurityManager securityManager = factory.getInstance();

        // SecurityManager实例绑定到SecurityUtils

        SecurityUtils.setSecurityManager(securityManager);

        // 获取当前执行的用户

        Subject currentUser = SecurityUtils.getSubject();

        // 创建token令牌,用户名/密码

        UsernamePasswordToken token = new UsernamePasswordToken(userName, password);

        try {

            // 身份验证

            currentUser.login(token);

            System.out.println("身份认证成功!");

        } catch (AuthenticationException e) {

            e.printStackTrace();

            System.out.println("身份认证失败!");

        }

        return currentUser;

    }

}

在pom.xml文件中添加junit依赖

<dependency>

    <groupId>junit</groupId>

    <artifactId>junit</artifactId>

    <version>4.12</version>

    <scope>test</scope>

</dependency>

测试用户的角色

@Test

public void testRoles() {

    Subject subject = ShiroUtils.login("classpath:shiro_role.ini", "wang", "12345");

    //判断一个角色

    boolean result = subject.hasRole("role1");

    System.out.println(result ? "role1角色" : "没有role1角色");

       

    //判断集合角色(可以单个判断角色)

    boolean[] results = subject.hasRoles(Arrays.asList("role1","role2","role3"));

    System.out.println(results[0] ? "role1角色" : "没有role1角色");

    System.out.println(results[1] ? "role2角色" : "没有role2角色");

    System.out.println(results[2] ? "role3角色" : "没有role3角色");

       

    //判断集合角色(只能判断都具备的角色)

    boolean resultAll = subject.hasAllRoles(Arrays.asList("role1","role2"));

    System.out.println(resultAll ? "role1,role2角色都有" : "role1,role2角色不全具备");

}

 

@Test

public void testCheckRoles() {

    Subject subject = ShiroUtils.login("classpath:shiro_role.ini", "wang", "12345");

    //检查角色,没有返回值,会抛出异常UnauthorizedException

    subject.checkRole("role1");

   

    //检查角色,如果有一个不符合的角色就异常

    subject.checkRoles("role1","role2","role3");

   

    subject.checkRoles(Arrays.asList("role1","role2"));

}

测试用户的权限

在src/main/resources中创建shiro_permission.ini文件

[users]

wang=12345,role1 //用户wang,密码12345,权限role1

zhangsan=12345,role2

 

[roles]

role1=user:select //权限user:select查询权限

role2=user:add,user:update,user.delete

@Test

public void testPermitted() {

    Subject subject = ShiroUtils.login("classpath:shiro_permission.ini", "wang", "12345");

    //单个查询权限

    System.out.println(subject.isPermitted("user:update") ? "有查询权限" : "没有查询权限");

    //测试多个权限

    boolean[] results = subject.isPermitted("user:update","user:select","user:add");

    System.out.println(results[0] ? "Update权限" : "没有update权限");

    System.out.println(results[1] ? "select权限" : "没有select权限");

    System.out.println(results[2] ? "add权限" : "没有add权限");

    //整体查询权限(权限之间为与的关系,只要一个为false,整个表达式为false)

    boolean result = subject.isPermittedAll("user:update","user:select","user:add");

    System.out.println(result ? "权限全都有" : "权限不完整");

    subject.logout();

}

   

@Test

public void testCheckPermitted() {

    Subject subject = ShiroUtils.login("classpath:shiro_permission.ini", "wang", "12345");

    //单个检查是否有权限,如果没有就会抛出UnauthorizedException异常

    subject.checkPermission("user:update");

   

    //整体检查权限(权限之间为与关系)

    subject.checkPermissions("user:update","user:select","user:add");

   

}

 

Shiro+Web验证用户的身份,角色,权限

创建一个maven工程,带框架maven-archetype-webapp1.0

创建后的maven工程是这个样子

 

 

没有看到src/main/java目录

这时可以在工程上单击右键Build PathàConfigure Build Path

 

将默认的JRE1.8删除,并重新添加

 

然后再次添加JRE

应用保存即可在工程中出现src/main/java目录

修改pom.xml文件,添加jar包

<dependency>

    <groupId>junit</groupId>

    <artifactId>junit</artifactId>

        <version>4.12</version>

        <scope>test</scope>

    </dependency>

    <dependency>

        <groupId>javax.servlet</groupId>

        <artifactId>javax.servlet-api</artifactId>

        <version>3.1.0</version>

        <scope>provided</scope>

    </dependency>

    <dependency>

        <groupId>javax.servlet.jsp</groupId>

        <artifactId>javax.servlet.jsp-api</artifactId>

        <version>2.3.1</version>

    </dependency>

    <dependency>

        <groupId>javax.servlet.jsp.jstl</groupId>

        <artifactId>jstl</artifactId>

        <version>1.2</version>

    </dependency>

    <!-- log4j -->

    <dependency>

        <groupId>log4j</groupId>

        <artifactId>log4j</artifactId>

        <version>1.2.17</version>

    </dependency>

    <!-- commons-logging -->

    <dependency>

        <groupId>commons-logging</groupId>

        <artifactId>commons-logging</artifactId>

        <version>1.2</version>

    </dependency>

    <!-- shiro-core -->

    <dependency>

        <groupId>org.apache.shiro</groupId>

        <artifactId>shiro-core</artifactId>

        <version>1.2.4</version>

    </dependency>

    <!-- shiro-web支持 -->

    <dependency>

        <groupId>org.apache.shiro</groupId>

        <artifactId>shiro-web</artifactId>

        <version>1.2.4</version>

    </dependency>

    <!-- slf4j-api -->

    <dependency>

        <groupId>org.slf4j</groupId>

        <artifactId>slf4j-api</artifactId>

        <version>1.7.12</version>

    </dependency>

这时我们发现Maven生成的文件夹格式需要调整

 

缺少META-INF文件夹,以及文件夹下的MANIFEST.MF文件

以及WEB-INF文件夹下的web.xml的内容也有问题

这时我们可以创建一个临时的动态Web工程,将WebContent下的META-INF文件夹,以及文件夹下的MANIFEST.MF文件拷贝到这个工程的webapp下即可,将临时动态工程的web.xml文件赋值一份到WEB-INF文件夹下替换即可。

标准的格式如下图

 

修改web.xml文件,添加Shiro过滤器和监听

<!-- Shiro-Web项目的入口 -->

<listener>

    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>

</listener>

 

<!-- Shiro支持 -->

<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>

创建shiro.ini文件

[main]

authc.loginUrl=/login //authc认证登录的url/login

[users]

wang=123456,admin  //用户wang,密码123456,拥有admin角色

jack=123,teacher

[roles]

admin=user:*  //admin角色拥有user:*的权限

teacher=student:*

[urls]

/login=anon  //对于/login访问可以匿名进行

/admin=authc //对于/admin访问时必须认证过

在webapp下创建页面

  1. login.jsp

<body>

    <form action="login" method="post">

        userName:<input name="userName" type="text"><br>

        password:<input name="password" type="password"><br>

        <input type="submit" value="login">

    </form>

</body>

  1. success.jsp欢迎页面

创建LoginServlet.java

public class LoginServlet extends HttpServlet{

 

    private static final long serialVersionUID = -7255349940789803107L;

 

    @Override

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        System.out.println("login doGet");

        request.getRequestDispatcher("login.jsp").forward(request, response);

       

    }

 

    @Override

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        System.out.println("login Post");

        String userName = request.getParameter("userName");

        String password = request.getParameter("password");

        Subject subject = SecurityUtils.getSubject();

        UsernamePasswordToken token = new UsernamePasswordToken(userName, password);

        try {

            subject.login(token);

                    //重定向客户端跳转,1.地址栏变化,2.request不传递

            response.sendRedirect("success.jsp"); //成功就重定向到success.jsp页面

        }catch(Exception e) {

            e.printStackTrace();

                     //请求转发:服务器端跳转,1.地址栏url不变,2.request值可以取得

            request.getRequestDispatcher("login.jsp").forward(request, response);

        }      

    }

}

创建AdminServlet.java

public class AdminServlet extends HttpServlet{

 

    private static final long serialVersionUID = -4834638728907791133L;

 

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("admin doget");

    }

 

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("admin dopost");

    }

}

修改web.xml

<servlet>

    <servlet-name>loginServlet</servlet-name>

    <servlet-class>com.kingsoft.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.kingsoft.servlet.AdminServlet</servlet-class>

</servlet>

<servlet-mapping>

    <servlet-name>adminServlet</servlet-name>

    <url-pattern>/admin</url-pattern>

</servlet-mapping>

 

测试拦截效果

1. http://localhost:8080/shiro-web/admin

由于/admin=authc //对于/admin访问时必须认证过

所以被转发回了http://localhost:8080/shiro-web/login

2. http://localhost:8080/shiro-web/login

如果输入了用户名wang 密码12345后拥有了admin角色

wang=123456,admin

 

修改shiro.ini

[main]

authc.loginUrl=/login

roles.unauthorizedUrl=/none.jsp

perms.unauthorizedUrl=/none.jsp

[users]

wang=123456,admin

jack=123,teacher

zhangsan=123

[roles]

admin=user:*

teacher=student:*

[urls]

/login=anon

/admin=authc

/student=roles[teacher]

创建none.jsp用于展示权限不足的页面

 

当在地址栏中输入:http://localhost:8080/shiro-web/login

并填写用户名:zhangsan 密码  123

时登录成功,但是zhangsan并不具备任何角色

 

在登录成功页面修改http://localhost:8080/shiro-web/student时显示权限不足,说明配置成功,因为/student必须拥有teacher角色才可以登录

/student=roles[teacher]

这时可以使用jack--123进行登录,才能拥有teacher角色

 

URL的匹配方式

1. 字符 ? 可以匹配单个字符 /admin?=authc 

可以匹配/admin3或/admin5或/adminx   但是不能匹配/admin23或admin

 

2. 字符 * 可以匹配多个字符 /admin*=authc

可以匹配/adminxyz,/admin234,/admin  但是不能匹配/adminxyxz/xyz

 

3. 字符**可以匹配多个路径  /admin/**=authc

可以匹配/admin/xyz/zyx这种多路径,但是不能匹配/admin234

 

4. 字符*/**可以任意匹配路径和多个字符   /admin*/**=authc

可以任意匹配/admin/zbc/xyz,    /admin123/abc/def  ,  /admin234 ,    /admin

 

Shiro标签

在success.jsp中使用Shiro标签用于展示用户的权限信息

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>

<!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>

    <shiro:hasRole name="admin"//admin角色登录显示

        欢迎有Admin角色的用户登录

<shiro:principal /> //显示登录人的信息

    </shiro:hasRole>

    <shiro:hasRole name="teacher"> //teacher角色登录显示

        欢迎有teacher角色的用户登录

<shiro:principal />

    </shiro:hasRole>

    <shiro:hasPermission name="student:*"> //拥有student:*的权限人登录信息

        欢迎有student:*权限的用户登录<shiro:principal />

    </shiro:hasPermission>

</body>

</html>

 

Shiro会话机制

一般管理会话,shiro也是调用serlvet容器中来进行,大概了解

修改LoginServlet.java

@Override

protected void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

    System.out.println("login Post");

    String userName = request.getParameter("userName");

    String password = request.getParameter("password");

    Subject subject = SecurityUtils.getSubject();

    UsernamePasswordToken token = new UsernamePasswordToken(userName, password);

    try {

        subject.login(token);

        Session session = subject.getSession();

        System.out.println("sessionId:"+session.getId());

        System.out.println("host:"+session.getHost());

        System.out.println("timeout:"+session.getTimeout());

        System.out.println("lastAccessTime:"+session.getLastAccessTime());

        session.setAttribute("info", session.getId());  //session传递

        response.sendRedirect("success.jsp");

    }catch(Exception e) {

        e.printStackTrace();

        request.getRequestDispatcher("login.jsp").forward(request, response);

    }

}

修改success.jsp

显示传递过来的session值

${info}<br>

 

 

自定义的Realm(之前的内容都是把用户的密码,角色,权限写在shiro.ini配置文件中),这次需要把相关的用户,角色,权限放在数据库中

修改之前的工程

在pom.xml中需要添加mysql的连接驱动

<dependency>

    <groupId>mysql</groupId>

    <artifactId>mysql-connector-java</artifactId>

    <version>5.1.40</version>

</dependency>

创建用户表t_user

 

创建角色表t_role

创建权限表t_permission

创建实体类User.java

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;

    }

}

创建连接数据库的工具类

import java.sql.Connection;

import java.sql.DriverManager;

 

public class DBUtils {

 

    public Connection getCon() throws Exception{

        Class.forName("com.mysql.jdbc.Driver");

        Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydata", "root", "123");

        return con;

    }

   

    public void closeCon(Connection con)throws Exception{

        if(con!=null){

            con.close();

        }

    }

   

    public static void main(String[] args) {

        DBUtils dbUtil=new DBUtils();

        try {

            dbUtil.getCon();

            System.out.println("数据库连接成功");

        } catch (Exception e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

            System.out.println("数据库连接失败");

        }

    }

}

创建UserDao.java

public class UserDao {

 

    public User getByUserName(Connection connection, String userName)throws Exception{

        User userResult = null;

        String sql = "select * from t_user where userName = ?";

        PreparedStatement pStatement = connection.prepareStatement(sql);

        pStatement.setString(1, userName);

        ResultSet rs = pStatement.executeQuery();

        if(rs.next()) {

            userResult = new User();

            userResult.setId(rs.getInt("id"));

            userResult.setUserName(rs.getString("userName"));

            userResult.setPassword(rs.getString("password"));

        }

        return userResult;

    }

 

    /**

     *

     * <b>Description</b><br>

     * (获取用户角色)

     * <br>

     * -------------------------------------------------<br>

     * <b>A我去  20191021 下午10:41:48</b>

     */

    public Set<String> getRoles(Connection connection, String userName)throws Exception{

        Set<String> roles = new HashSet<String>();

        String sql = "SELECT r.roleName FROM t_role r JOIN t_user u ON r.id = u.roleId AND u.userName = ?";

        PreparedStatement pStatement = connection.prepareStatement(sql);

        pStatement.setString(1, userName);

        ResultSet resultSet = pStatement.executeQuery();

        while(resultSet.next()) {

            roles.add(resultSet.getString("roleName"));

        }

        return roles;

    }

 

    /**

     *

     * <b>Description</b><br>

     * (获取用户的权限)

     * <br>

     * -------------------------------------------------<br>

     * <b>A我去  20191021 下午10:41:22</b>

     */

    public Set<String> getPermissions(Connection connection, String userName)

throws Exception{

        Set<String> permissions = new HashSet<String>();

        String sql = "SELECT p.perName FROM t_user u JOIN t_permission p ON p.roleId= u.roleId JOIN t_role r ON u.roleId=r.id WHERE u.userName = ?";

        PreparedStatement pStatement = connection.prepareStatement(sql);

        pStatement.setString(1, userName);

        ResultSet resultSet = pStatement.executeQuery();

        while(resultSet.next()) {

            permissions.add(resultSet.getString("perName"));

        }

        return permissions;

    }

}

创建自定义的MyRealm.java

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.kingsoft.dao.UserDao;

import com.kingsoft.entity.User;

import com.kingsoft.utils.DBUtils;

 

public class MyRealm extends AuthorizingRealm{

   

    private UserDao userDao = new UserDao();

    private DBUtils utils = new DBUtils();

 

    /**

     * 为登录成功的用户授权

     */

    @Override

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        String userName = (String)principals.getPrimaryPrincipal();

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        Connection connection = null;

        try {

            connection = utils.getCon();

            authorizationInfo.setRoles(userDao.getRoles(connection,userName));

            authorizationInfo.setStringPermissions(userDao.getPermissions(connection, userName));

           

        }catch(Exception e) {

            e.printStackTrace();

        }finally {

            try {

                utils.closeCon(connection);

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

        return authorizationInfo;

    }

 

    /**

     * 验证当前登录的用户

     */

    @Override

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        String userName = (String)token.getPrincipal();

        Connection connection = null;

        try {

            connection = utils.getCon();

            User user = userDao.getByUserName(connection, userName);

            if(user!=null) {

                AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(

user.getUserName(),user.getPassword(),"aa");

                return authcInfo;

            }else {

                return null;

            }

        }catch(Exception e) {

            e.printStackTrace();

        }finally {

            try {

                utils.closeCon(connection);

            } catch (Exception e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

        }

        return null;

    }

}

创建LoginServlet.java

public class LoginServlet extends HttpServlet {

 

    private static final long serialVersionUID = -7255349940789803107L;

 

    @Override

    protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {

        System.out.println("login doGet");

        request.getRequestDispatcher("login.jsp").forward(request, response);

 

    }

 

    @Override

    protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {

        System.out.println("login Post");

        String userName = request.getParameter("userName");

        String password = request.getParameter("password");

        Subject subject = SecurityUtils.getSubject();

        UsernamePasswordToken token = new UsernamePasswordToken(userName, password);

        try {

            subject.login(token);

            Session session = subject.getSession();

            System.out.println("sessionId:" + session.getId());

            System.out.println("host:" + session.getHost());

            System.out.println("timeout:" + session.getTimeout());

            System.out.println("lastAccessTime:" + session.getLastAccessTime());

            session.setAttribute("info", session.getId());

            response.sendRedirect("success.jsp");

        } catch (Exception e) {

            e.printStackTrace();

            request.getRequestDispatcher("login.jsp").forward(request, response);

        }

    }

}

加密

在工具包utils下创建EncryptionUtils.java

package com.kingsoft.utils;

 

import org.apache.shiro.codec.Base64;

import org.apache.shiro.crypto.hash.Md5Hash;

 

public class EncryptionUtils {

 

    /**

     *

     * <b>Description</b><br>

     * (Base64加密)

     * <br>

     * -------------------------------------------------<br>

     * <b>A我去  20191022 下午9:24:26</b>

     */

    public static String encBase64(String str) {

        return Base64.encodeToString(str.getBytes());

    }

   

    /**

     *

     * <b>Description</b><br>

     * (Base64解密)

     * <br>

     * -------------------------------------------------<br>

     * <b>A我去  20191022 下午9:26:29</b>

     */

    public static String decBase64(String str) {

        return Base64.decodeToString(str);

    }

   

    /**

     *

     * <b>Description</b><br>

     * (MD5加密,salt加盐)

     * <br>

     * -------------------------------------------------<br>

     * <b>A我去  20191022 下午9:34:49</b>

     */

    public static String encMD5(String source, String salt) {

        return new Md5Hash(source, salt).toString();

    }

   

    /**

     *

     * <b>Description</b><br>

     * (MD5加密,salt加盐,num散列的次数)

     * <br>

     * -------------------------------------------------<br>

     * <b>A我去  20191022 下午9:37:35</b>

     */

    public static String encMD5(String source, String salt, int num) {

        return new Md5Hash(source, salt, num).toString();

    }

   

    public static void main(String[] args) {

        String str = "a";

        String str1 = "YQ==";

        System.out.println("Base64加密:"+EncryptionUtils.encBase64(str));

        System.out.println("Base64解密:"+EncryptionUtils.decBase64(str1));

        System.out.println("MD5加盐加密:"+EncryptionUtils.encMD5(str, "abc123"));

        System.out.println("MD5加盐加密64次散列:"+EncryptionUtils.encMD5(str, "abc123", 64));

    }

}

以后可以将加密的字符串插入用户表的密码中,当登录时就会比对用户表中的密码,还需修改登录Servlet

修改LoginServlet.java

String userName = request.getParameter("userName");

String password = request.getParameter("password");

Subject subject = SecurityUtils.getSubject();

UsernamePasswordToken token = new UsernamePasswordToken

(userName, EncryptionUtils.encMD5(password, "abc123"));

一般都会把”abc123”称为盐,一般情况下这个盐放在配置文件中保存

Shiro+Spring整合

创建Maven工程

 

 

单击“Finish”完成创建Maven工程

 

 

创建出的Maven工程没有src/main/java目录

 

在工程上单击右键Build Path àConfigure Build Path…

将默认的JRE删除,并单击”Add Library”重新添加JRE运行库

 

选择JRE System Library

选择默认的工作空间JRE

应用并保存后,可以看到src/main/java目录出现了

 

接下来我们看默认生成的webapp目录格式也不对

这时我们可以创建一个临时的动态Web工程将对应的目录和web.xml文件拷贝一下

以上操作就可以创建出标准的Maven  web工程

修改pom.xml文件,引入对应的jar包

<dependencies>

        <dependency>

            <groupId>junit</groupId>

            <artifactId>junit</artifactId>

            <version>4.12</version>

            <scope>test</scope>

        </dependency>

        <!-- 添加Servlet支持 -->

        <dependency>

            <groupId>javax.servlet</groupId>

            <artifactId>javax.servlet-api</artifactId>

            <version>3.1.0</version>

        </dependency>

        <dependency>

            <groupId>javax.servlet.jsp</groupId>

            <artifactId>javax.servlet.jsp-api</artifactId>

            <version>2.3.1</version>

        </dependency>

        <!-- 添加jtl支持 -->

        <dependency>

            <groupId>javax.servlet.jsp.jstl</groupId>

            <artifactId>jstl</artifactId>

            <version>1.2</version>

        </dependency>

 

        <!-- 添加Spring支持 -->

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-core</artifactId>

            <version>4.1.7.RELEASE</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-beans</artifactId>

            <version>4.1.7.RELEASE</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-tx</artifactId>

            <version>4.1.7.RELEASE</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-context</artifactId>

            <version>4.1.7.RELEASE</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-context-support</artifactId>

            <version>4.1.7.RELEASE</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-web</artifactId>

            <version>4.1.7.RELEASE</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-webmvc</artifactId>

            <version>4.1.7.RELEASE</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-aop</artifactId>

            <version>4.1.7.RELEASE</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-aspects</artifactId>

            <version>4.1.7.RELEASE</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-jdbc</artifactId>

            <version>4.1.7.RELEASE</version>

        </dependency>

        <dependency>

            <groupId>org.mybatis</groupId>

            <artifactId>mybatis-spring</artifactId>

            <version>1.2.3</version>

        </dependency>

        <!-- 添加日志支持 -->

        <dependency>

            <groupId>log4j</groupId>

            <artifactId>log4j</artifactId>

            <version>1.2.17</version>

        </dependency>

        <!-- 添加mybatis支持 -->

        <dependency>

            <groupId>org.mybatis</groupId>

            <artifactId>mybatis</artifactId>

            <version>3.3.0</version>

        </dependency>

        <!-- jdbc驱动包 -->

        <dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

            <version>5.1.40</version>

        </dependency>

        <dependency>

            <groupId>org.apache.shiro</groupId>

            <artifactId>shiro-core</artifactId>

            <version>1.2.4</version>

        </dependency>

        <dependency>

            <groupId>org.slf4j</groupId>

            <artifactId>slf4j-log4j12</artifactId>

            <version>1.7.12</version>

        </dependency>

        <dependency>

            <groupId>org.apache.shiro</groupId>

            <artifactId>shiro-web</artifactId>

            <version>1.2.4</version>

        </dependency>

        <dependency>

            <groupId>org.apache.shiro</groupId>

            <artifactId>shiro-spring</artifactId>

            <version>1.2.4</version>

        </dependency>

    </dependencies>

 

创建包

创建实体类

package com.kingsoft.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

public interface UserDao {

 

    /**

     * 通过用户名查询用户

     */

    public User getByUserName(String userName);

   

    /**

     * 通过用户名查询角色信息

     */

    public Set<String> getRoles(String userName);

   

    /**

     * 通过用户名查询权限信息

     */

    public Set<String> getPermissions(String userName);

}

 

创建UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.kingsoft.dao.UserDao">

 

    <resultMap type="User" id="UserResult">

        <result property="id" column="id" />

        <result property="userName" column="userName" />

        <result property="password" column="password" />

    </resultMap>

 

    <select id="getByUserName" parameterType="String"

        resultMap="UserResult">

        select * from t_user where userName=#{userName}

    </select>

 

    <select id="getRoles" parameterType="String" resultType="String">

        select r.roleName from t_user u,t_role r where u.roleId=r.id and u.userName=#{userName}

    </select>

 

    <select id="getPermissions" parameterType="String" resultType="String">

        select p.perName from t_user u,t_role r,t_permission p

        where u.roleId=r.id and p.roleId=r.id and u.userName=#{userName}

    </select>

</mapper>

创建UserService.java接口

public interface UserService {

 

    /**

     * 通过用户名查询用户

     * @param userName

     * @return

     */

    public User getByUserName(String userName);

   

    /**

     * 通过用户名查询角色信息

     * @param userName

     * @return

     */

    public Set<String> getRoles(String userName);

   

    /**

     * 通过用户名查询权限信息

     * @param userName

     * @return

     */

    public Set<String> getPermissions(String userName);

}

 

创建UserServiceImpl.java实现类

@Service("userService")

public class UserServiceImpl implements UserService{

 

    @Resource

    private UserDao userDao;

   

    public User getByUserName(String userName) {

        return userDao.getByUserName(userName);

    }

 

    public Set<String> getRoles(String userName) {

        return userDao.getRoles(userName);

    }

 

    public Set<String> getPermissions(String userName) {

        return userDao.getPermissions(userName);

    }

}

创建UserController.java

@Controller

@RequestMapping("/user")

public class UserController {

 

    @RequestMapping("/login")

    public String login(User user,HttpServletRequest request){

        Subject subject=SecurityUtils.getSubject();

        UsernamePasswordToken token=new UsernamePasswordToken(user.getUserName(), user.getPassword());

        try{

            subject.login(token);

            Session session=subject.getSession();

            System.out.println("sessionId:"+session.getId());

            System.out.println("sessionHost:"+session.getHost());

            System.out.println("sessionTimeout:"+session.getTimeout());

            session.setAttribute("info", "session的数据");

            return "redirect:/success.jsp";

        }catch(Exception e){

            e.printStackTrace();

            request.setAttribute("user", user);

            request.setAttribute("errorMsg", "用户名或密码错误!");

            return "index";

        }

    }

}

 

创建MyRealm.java

public class MyRealm extends AuthorizingRealm{

   

    @Resource

    private UserService userService;

 

    /**

     * 为当限前登录的用户授予角色和权

     */

    @Override

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        String userName=(String)principals.getPrimaryPrincipal();

        SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();

        authorizationInfo.setRoles(userService.getRoles(userName));

        authorizationInfo.setStringPermissions(userService.getPermissions(userName));

        return authorizationInfo;

    }

 

    /**

     * 验证当前登录的用户

     */

    @Override

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        String userName=(String)token.getPrincipal();

        User user=userService.getByUserName(userName);

        if(user!=null){

            AuthenticationInfo authcInfo=new SimpleAuthenticationInfo

(user.getUserName(),user.getPassword(),"xx");

            return authcInfo;

        }else{

            return null;               

        }

    }

}

创建配置文件在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 

创建mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE configuration

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

    <!-- 别名 -->

    <typeAliases>

        <package name="com.kingsoft.entity"/>

    </typeAliases>

</configuration>

 

创建spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>   

<beans xmlns="http://www.springframework.org/schema/beans"   

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

    xmlns:p="http://www.springframework.org/schema/p" 

    xmlns:aop="http://www.springframework.org/schema/aop"  

    xmlns:context="http://www.springframework.org/schema/context" 

    xmlns:jee="http://www.springframework.org/schema/jee" 

    xmlns:tx="http://www.springframework.org/schema/tx" 

    xsi:schemaLocation="   

        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 

        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 

        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd 

        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd 

        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">   

 

    <!-- 使用注解的包,包括子集 -->

    <context:component-scan base-package="com.kingsoft.controller" />

 

    <!-- 视图解析器 -->

    <bean id="viewResolver"

        class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <property name="prefix" value="/" />

        <property name="suffix" value=".jsp"></property>

    </bean>

 

</beans> 

创建applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>   

<beans xmlns="http://www.springframework.org/schema/beans"   

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

    xmlns:p="http://www.springframework.org/schema/p" 

    xmlns:aop="http://www.springframework.org/schema/aop"  

    xmlns:context="http://www.springframework.org/schema/context" 

    xmlns:jee="http://www.springframework.org/schema/jee" 

    xmlns:tx="http://www.springframework.org/schema/tx"  

    xsi:schemaLocation="   

        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 

        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 

        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd 

        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd 

        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">   

       

    <!-- 自动扫描Service -->

    <context:component-scan base-package="com.kingsoft.service" />

   

    <!-- 配置数据源 -->

    <bean id="dataSource"

        class="org.springframework.jdbc.datasource.DriverManagerDataSource">

        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>

        <property name="url" value="jdbc:mysql://localhost:3306/mydata"/>

        <property name="username" value="root"/>

        <property name="password" value="123"/>

    </bean>

 

    <!-- 配置mybatissqlSessionFactory -->

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

        <property name="dataSource" ref="dataSource" />

        <!-- 自动扫描mappers.xml文件 -->

        <property name="mapperLocations" value="classpath:com/kingsoft/mappers/*.xml">

</property>

        <!-- mybatis配置文件 -->

        <property name="configLocation" value="classpath:mybatis-config.xml"></property>

    </bean>

 

    <!-- DAO接口所在包名,Spring会自动查找其下的类 -->

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

        <property name="basePackage" value="com.kingsoft.dao" />

        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>

    </bean>

 

    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->

    <bean id="transactionManager"

        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

        <property name="dataSource" ref="dataSource" />

    </bean>

   

    <!-- 自定义Realm -->

    <bean id="myRealm" class="com.kingsoft.realm.MyRealm"/> 

   

    <!-- 安全管理器 -->

    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 

      <property name="realm" ref="myRealm"/> 

    </bean> 

   

    <!-- Shiro过滤器 -->

    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 

        <!-- Shiro的核心安全接口,这个属性是必须的 --> 

        <property name="securityManager" ref="securityManager"/>

        <!-- 身份认证失败,则跳转到登录页面的配置 --> 

        <property name="loginUrl" value="/index.jsp"/>

        <!-- 权限认证失败,则跳转到指定页面 --> 

        <property name="unauthorizedUrl" value="/unauthor.jsp"/> 

        <!-- Shiro连接约束配置,即过滤链的定义 --> 

        <property name="filterChainDefinitions"> 

            <value> 

                /login=anon

                /admin*=authc

                /student=roles[teacher]

                /teacher=perms["user:create"]

            </value> 

        </property>

    </bean> 

   

    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 --> 

<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> 

   

    <!-- 开启Shiro注解 -->

    <bean class="org.springframework.aop.framework.autoproxy

.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/> 

        <bean class="org.apache.shiro.spring.security

.interceptor.AuthorizationAttributeSourceAdvisor"> 

      <property name="securityManager" ref="securityManager"/> 

    </bean> 

 

    <!-- 配置事务通知属性 --> 

    <tx:advice id="txAdvice" transaction-manager="transactionManager"> 

        <!-- 定义事务传播属性 --> 

        <tx:attributes> 

            <tx:method name="insert*" propagation="REQUIRED" /> 

            <tx:method name="update*" propagation="REQUIRED" /> 

            <tx:method name="edit*" propagation="REQUIRED" /> 

            <tx:method name="save*" propagation="REQUIRED" /> 

            <tx:method name="add*" propagation="REQUIRED" /> 

            <tx:method name="new*" propagation="REQUIRED" /> 

            <tx:method name="set*" propagation="REQUIRED" /> 

            <tx:method name="remove*" propagation="REQUIRED" /> 

            <tx:method name="delete*" propagation="REQUIRED" /> 

            <tx:method name="change*" propagation="REQUIRED" /> 

            <tx:method name="check*" propagation="REQUIRED" /> 

            <tx:method name="get*" propagation="REQUIRED" read-only="true" /> 

            <tx:method name="find*" propagation="REQUIRED" read-only="true" /> 

            <tx:method name="load*" propagation="REQUIRED" read-only="true" /> 

            <tx:method name="*" propagation="REQUIRED" read-only="true" /> 

        </tx:attributes> 

    </tx:advice> 

 

    <!-- 配置事务切面 --> 

    <aop:config> 

        <aop:pointcut id="serviceOperation" 

            expression="execution(* com.kingsoft.service.*.*(..))" /> 

        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" /> 

    </aop:config> 

   

  

</beans>

 

修改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>ShiroWeb2</display-name>

    <welcome-file-list>

        <welcome-file>index.jsp</welcome-file>

    </welcome-file-list>

 

    <!-- shiro过滤器定义 -->

    <filter>

        <filter-name>shiroFilter</filter-name>

        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

        <init-param>

            <!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 -->

            <param-name>targetFilterLifecycle</param-name>

            <param-value>true</param-value>

        </init-param>

    </filter>

    <filter-mapping>

        <filter-name>shiroFilter</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

 

 

    <!-- Spring配置文件 -->

    <context-param>

        <param-name>contextConfigLocation</param-name>

        <param-value>classpath:applicationContext.xml</param-value>

    </context-param>

    <!-- 编码过滤器 -->

    <filter>

        <filter-name>encodingFilter</filter-name>

        <filter-class>

                        org.springframework.web.filter.CharacterEncodingFilter

        </filter-class>

        <async-supported>true</async-supported>

        <init-param>

            <param-name>encoding</param-name>

            <param-value>UTF-8</param-value>

        </init-param>

    </filter>

    <filter-mapping>

        <filter-name>encodingFilter</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

    <!-- Spring监听器 -->

    <listener>

        <listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

    </listener>

 

    <!-- 添加对springmvc的支持 -->

    <servlet>

        <servlet-name>springMVC</servlet-name>

        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <init-param>

            <param-name>contextConfigLocation</param-name>

            <param-value>classpath:spring-mvc.xml</param-value>

        </init-param>

        <load-on-startup>1</load-on-startup>

        <async-supported>true</async-supported>

    </servlet>

    <servlet-mapping>

        <servlet-name>springMVC</servlet-name>

        <url-pattern>*.do</url-pattern>

    </servlet-mapping>

 

</web-app>

 

创建登录和验证成功页面

创建index.jsp

<form action="${pageContext.request.contextPath }/user/login.do" method="post">

    userName:<input type="text" name="userName" value="${user.userName }"/><br/>

    password:<input type="password" name="password" value="${user.password }"><br/>

    <input type="submit" value="login"/><font color="red">${errorMsg }</font>

</form>

创建success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

<!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>

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值