首先说一下shiro在web程序中的运作流程
shiro就像是一个包裹着web应用程序的罩子,所有的用户请求都需要经过shiro这一层罩子,经过shiro这层罩子以后,就会接着通过一条循环的过滤器链,从上到下通过,在经过与该请求适配的过滤器时就会对该请求进行检测如果检测通过那么就返回该请求的结果,否则就跳转到相应的失败页面。流程如下图所示:
首先我们先配置shiro的依赖,SSM框架的依赖请各位自行导入
<!-- ============ shiro ============ --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.4.0</version> </dependency>
之后便是配置MVC的web.xml文件
<web-app> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
之后就是相应的mvc.xml文件
beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 告知springmvc 哪些包中 存在 被注解的类 use-default-filters="false" 遇到到 @Controller @Service @Repository @Component类,都会忽略 --> <context:component-scan base-package="com.qianfeng" use-default-filters="false"> <!-- 只扫描 有@Controller注解的类 --> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 注册注解开发驱动 --> <mvc:annotation-driven></mvc:annotation-driven> <!-- 视图解析器 作用:1.捕获后端控制器的返回值="index" 2.解析: 在返回值的前后 拼接 ==> "/index.jsp" --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property><!-- 前缀 --> <property name="suffix" value=".jsp"></property><!-- 后缀 --> </bean> <!-- 在项目中 自动添加一个 映射{"/**" : DefaultServletHttpRequestHandler} 请求进入前端后,会先匹配自定义的Handler,如果没有匹配的则进入DefaultServletHttpRequestHandler。 DefaultServletHttpRequestHandler会将请求转发给Tomcat中名为"default"的servlet。 最终实现了静态资源的访问 --> <mvc:default-servlet-handler/> </beans>
之后我们编写一个简单的页面来实现用户身份信息的校验
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登陆页面</title> </head> <style> label{ display: block; } </style> <body> <form action="/user/login" method="post"> <label>用户名: <input type="text" name="username"></label> <label>密码: <input type="text" name="password"></label> <input type="submit" value="登陆"> </form> </body> </html>
之后我们编写一个User的实体类
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class User { private Integer id; private String username; private String password; }
之后我们编写一个简单的controller类来进行简单的逻辑验证
mport com.qianfeng.pojo.User; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/user") public class UserController { @GetMapping("/login") public String login() { System.out.println("go to login"); return "login"; } @PostMapping("/login") public String loginLogic(User user) { System.out.println("login logic"); //获取subject Subject subject=SecurityUtils.getSubject(); //创建令牌 UsernamePasswordToken token=new UsernamePasswordToken(user.getUsername(),user.getPassword()); //登录失败抛出异常,交由异常解析器 subject.login(token); return "index"; } @RequestMapping("/all") public String queryAllUsers() { System.out.println("query all users"); return "index"; } @RequestMapping("/perms/error") public String performer() { System.out.println("权限不足"); return "error"; } }
之后我们便可以运行程序查看实际的运行过程,可以发现当用户未登录或者登陆失败时都会重新跳转到登陆界面来。如图所示: