前面两节内容介绍了Shiro中是如何进行身份和权限的认证,但是只是单纯的进行Shiro的验证,简单一点的话,用的是.ini配置文件,也举了个使用jdbc realm的例子,这篇主要来总结一下Shiro是如何集成web的,即如何用在web工程中。
本文没有使用web框架,比如springmvc或者struts2,用的是原始的servlet,使用的是.ini配置文件,旨在简单粗暴,说明问题。
下面来总结一下Shiro集成web的步骤。
1. 配置
1.1 web.xml配置
Shiro如果想要集成到web中,首先需要在web.xml中配置Shiro的监听器和过滤器,如下:
<!-- 添加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> <init-param> <param-name>configPath</param-name> <param-value>/WEB-INF/shiro.ini</param-value> </init-param> </filter> <filter-mapping> <filter-name>ShiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
由上面的配置可以看出,定义Shiro配置文件的路径在/WEE-INF/shiro.ini文件,Shiro的过滤器将会拦截所有的请求。web.xml中其他配置就是servlet的映射配置了,不同的servlet对应不同的请求url,如下:
<servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>demo.shiro.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>demo.shiro.servlet.AdminServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>AdminServlet</servlet-name> <url-pattern>/admin</url-pattern> </servlet-mapping> <servlet> <servlet-name>TeacherRoleServlet</servlet-name> <servlet-class>demo.shiro.servlet.TeacherRoleServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>TeacherRoleServlet</servlet-name> <url-pattern>/student</url-pattern> </servlet-mapping> <servlet-mapping> <servlet> <servlet-name>LogoutServlet</servlet-name> <servlet-class>demo.shiro.servlet.LogoutServlet</servlet-class> </servlet> <servlet-name>LogoutServlet</servlet-name> <url-pattern>/logout</url-pattern> </servlet-mapping> <servlet> <servlet-name>TeacherPermsServlet</servlet-name> <servlet-class>demo.shiro.servlet.TeacherPermsServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>TeacherPermsServlet</servlet-name> <url-pattern>/teacher</url-pattern> </servlet-mapping>
1.2 pom.xml配置
pom文件中需要引入相关的jar
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>demo.shiro</groupId> <artifactId>ShiroWeb</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <dependencies> <!-- shiro核心包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.5</version> </dependency> <!-- 添加shiro web支持 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.5</version> </dependency> <!-- 添加sevlet支持 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <!-- 添加jsp支持 --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> </dependency> <!-- 添加jstl支持 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- 添加log4j日志 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>ShiroWeb</finalName> </build> </project>
2. Shiro的内置过滤器(Default Filters)
当运行Web应用程序时,Shiro将创建一些有用的内置过滤器实例,并且自动的在[main]部分使用。我们可以人为配置它们,就好比spring中的bean一样,并且在自己定义的url中引用它们。Shiro中内置的过滤器有以下几个:
这些内置的过滤器使用方法是这样的,一般先指定一个请求url对应一个过滤器名,由于该过滤器对应一个类,而这个类中会有一个属性,这个属性是当验证失败的时候指定要跳转到那个url的,所以将这个属性配置成验证失败后你要请求的url即可。这里我举其中几个(匿名,身份验证,许可验证,权限验证)来说明如何使用,其他的类似。
3. Shiro的配置文件
针对上面我提到的几个验证,先把shiro.ini文件写好:
[main] #定义身份认证失败后的请求url映射,loginUrl是身份认证过滤器中的一个属性 authc.loginUrl=/login #定义角色认证失败后的请求url映射,unauthorizedUrl是角色认证过滤器中的一个属性 roles.unauthorizedUrl=/unauthorized.jsp #定义角色认证失败后请求url映射,unauthorizedUrl是角色认证过滤器中的一个属性 perms.unauthorizedUrl=/unauthorized.jsp #定义几个用户和角色 [users] csdn1=123,admin,teacher csdn2=123,teacher csdn3=123,student csdn4=123 #定义不同角色的权限 [roles] admin=user:*,student:* teacher=student:* #定义请求的地址需要做什么验证 [urls] #请求login的时候不需要权限,游客身份即可(anon) /login=anon #请求/admin的时候,需要身份认证(authc) /admin=authc #请求/student的时候,需要角色认证,必须是拥有teacher角色的用户才行 /student=roles[teacher] #请求/teacher的时候,需要权限认证,必须是拥有user:create权限的角色的用户才行 /teacher=perms["user:create"]
我简单说明一下这个配置,比如[main]中定义的authc.loginUrl=/login,authc是一个内置过滤器,它对应org.apache.shiro.web.filter.authc.AnonymousFilter类,而这个类中有个loginUrl属性,表示验证失败后将要请求的url映射,这个url映射与一个具体的servlet对应,读到这里,可以和上面的servlet配置对比一下就知道了。roles.unauthorizedUrl也是一样的道理,只不过这里验证失败直接请求一个具体的jsp页面而已。
[users]中是Subject认证主体,就不再赘述了,[urls]中定义需要拦截哪些请求,并做什么验证。比如/login的url映射请求不拦截,因为是登陆的,请求/admin的url映射的话做身份认证,请求/student的url映射的话要做角色认证,且必须是teacher角色才行,请求/teacher的url映射的话需要进行权限认证,必须有user:create权限的用户才可以通过验证。
4. 测试程序
接下来一个个测试上面的这些认证。
4.1 测试authc身份认证
测试authc,得有/admin请求,加上上面的servlet配置可知,首先完成LoginServlet和AdminServlet。
//LoginServlet.java public class LoginServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("login doGet"); String username = request.getParameter("username"); String password = request.getParameter("password"); Subject currentUser = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, password); try { currentUser.login(token); System.out.println("认证成功"); request.getSession().setAttribute("username", username); request.getRequestDispatcher("/success.jsp").forward(request, response); } catch (AuthenticationException e) { e.printStackTrace(); System.out.println("认证失败"); request.getRequestDispatcher("/login.jsp").forward(request, response); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
认证成功跳转到success.jsp页面,认证失败的话就进入登录页面,让用户先登录,看一下success.jsp和login.jsp
<form action="${pageContext.request.contextPath }/login" method="post"> username:<input type="text" name="username"/><br> password:<input type="password" name="password"/><br> <input type="submit" value="登陆"> </form>
因为登录提交请求的是/login,而/login=anon表示匿名验证,所以不会拦截认证,直接进入LoginServlet,执行我们自己写的认证代码。下面是success.jsp,很简单。
<body> 欢迎你${username } <a href="${pageContext.request.contextPath }/logout">退出</a> </body>
顺带把LogoutServlet写了:
public class LogoutServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getSession().invalidate(); //直接让session失效 } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
然后就是/admin请求了,请求的是AdminServlet.jsp,如果认证成功就会进入该servlet:
public class AdminServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("admin doGet"); request.getRequestDispatcher("/success.jsp").forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
写好了之后,开启tomcat,在浏览器中访问:http://localhost:8080/ShiroWeb/admin来请求AdminServlet.java,Shiro根据配置(/admin=authc)会去进行身份认证,但是此时肯定是认证失败,所以根据配置(authc.loginUrl=/login)去请求LoginServlet.java,Shiro不会去验证,因为/login=anon,但是LoginServlet.java程序中会验证,我们自己写的。因为没有用户名和密码,所以认证失败,会跳转到login.jsp登陆页面,输入用户名和密码后,再次请求/login,此时再次进入LoginServlet.java,认证成功,进入success.jsp页面。
因为Shiro中会默认有30分钟缓存时间,所以此时我们再次去访问http://localhost:8080/ShiroWeb/admin的时候,就可以访问到AdminServlet.java中了,可以在里面打断点验证,然后掉转到success.jsp。这就是身份认证的过程。
4.2 测试roles角色认证
根据配置文件,我们需要请求/student才能触发roles角色认证,所以根据servlet的映射,我们完成TeacherRoleServlet.java代码。
public class TeacherRoleServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("role deget"); Subject currentUser = SecurityUtils.getSubject(); //其实是不用判断了,因为只要进来了,肯定角色是对的,否则进不来 //判断当前用户是否具有teacher角色 if(currentUser.hasRole("teacher")) { request.getRequestDispatcher("/success.jsp").forward(request, response); } else { request.getRequestDispatcher("/unauthorized.jsp").forward(request, response); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
上面程序的注释中也提到了,其实可以不用再认证了,因为进入该servlet之前,Shiro已经帮我们认证了,只有认证成功才会进入到该servlet,否则会根据配置(roles.unauthorizedUrl=/unauthorized.jsp)会直接跳转到unauthorized.jsp页面显示。
<body> 认证未通过,或者权限不足 <a href="${pageContext.request.contextPath }/logout">退出</a> </body>
然后我们在浏览器中输入http://localhost:8080/ShiroWeb/student来请求TeacherRoleServlet,这里需要注意的是,刚刚测试过后需要点击退出,否则还是当前用户,会影响这次的测试。在测试角色认证的时候,它会先进行身份认证,再进行角色认证。也就是说,Shiro会先跳转到登陆页面让我们登陆,我们可以尝试两个不同的用户csdn1(有teacher角色)和csdn3(没有teacher角色)来测试。
4.2 测试perms权限认证
和上面一样,先写TeacherPermsServlet.java:
public class TeacherPermsServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("perms doget"); Subject currentUser = SecurityUtils.getSubject(); // 其实是不用判断了,因为只要进来了,肯定角色是对的,否则进不来 // 判断当前用户是否具有teacher角色 if (currentUser.isPermitted("user:create")) { request.getRequestDispatcher("/success.jsp").forward(request, response); } else { request.getRequestDispatcher("/unauthorized.jsp").forward(request, response); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
然后我们在浏览器中输入http://localhost:8080/ShiroWeb/teacher来请求TeacherPermsServlet ,这里同样需要注意的是,刚刚测试过后需要点击退出,否则还是当前用户,会影响这次的测试。在测试权限认证的时候,它同样会先进行身份认证,再进行权限认证。也就是说,Shiro会先跳转到登陆页面让我们登陆,我们可以尝试两个不同的用户csdn1(有admin角色,从而有user:create权限)和csdn3(没有admin角色,从而没有user:create权限)来测试。
5. url匹配方式
这里提一下Shiro在集成web的时候,url可以不用向上面那样写的很死,它可以匹配的,比如:
/admin?=authc,表示可以请求以admin开头的字符串,如xxx/adminfefe,但无法匹配多个,即xxx/admindf/admin是不行的
/admin*=authc表示可以匹配零个或者多个字符,如/admin,/admin1,/admin123,但是不能匹配/admin/abc这种
/admin/**=authc表示可以匹配零个或者多个路径,如/admin,/admin/ad/adfdf等。
/admin*/**=authc这个就不多说了,结合上面两个就知道了。
相关推荐
shiro web集成方向api,chm格式的。
-- Shiro's main business-tier object for web-enabled applications --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> ...
使用admin 000000登录即可,在启动项目前要启动redis
Apache Shiro是一个功能强大、灵活的开放式安全框架,干净利落地处理身份验证、授权...Shiro可以帮助我们完成:认证、授权、加密、会话管理、与Web集成、缓存等。 【apache-shiro-1-2-x-reference,"waylau"翻译自官网】
<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <!--cookie的name,我故意取名叫xxxxbaidu --> <constructor-arg value="v_v-s-baidu"/> <!--cookie的有效时间 --&...
记录一下使用SpringBoot集成Shiro框架和Jwt框架实现前后端分离Web项目的过程,后端使用SpringBoot整合Shiro+Jwt(auth0),前端使用vue+elementUI框架,前后端的交互使用的是jwt的token,shiro的会话关闭,后端只需要...
使用SpringBoot集成Shiro框架实现前后端分离Web项目,后端使用SpringBoot整合Shiro,前端使用vue+elementui,达到前后端使用token来进行交互的应用,这种方式通常叫做无状态,后端只需要使用Shiro框架根据前端传来的...
shiro 与 spring web 项目集成 #资源达人分享计划 # 技术文档
• 在任何环境下使用 Session API,即使没有Web 或 EJB 容器。 • 在身份验证,访问控制期间或在会话的生命周期,对事件作出反应。 • 聚集一个或多个用户安全数据的数据源,并作为一个单一的复合用户“视图”。 • ...
web项目集成shiro demo,这是web项目集成shiro的一个综合案例
Spring+SpringMVC+MyBatis+Shiro+Maven集成web项目 可以直接使用
shiro安全框架集成web简介,用户初步了解shiro的简单案例
Shiro Stormpath 示例演示在使用 Shiro 作为安全框架的 Web 应用程序中使用 Stormpath 后端的应用程序。配置您必须拥有 Stormpath 帐户并创建了一个应用程序。 按照以下模板,在您的 Maven 用户设置中创建一个默认...
4、优点:快速上手、全面支持验证、授权、加密和会话、灵活自定义设计、支持web环境、可以无缝集成spring等优点。可以用来用户验证、用户授权、用户session管理、安全加密等 5、基于RBAC五张表:用户表 tb_user、...
15.web集成-shiro默认过滤器.avi 16.web集成-authc拦截器工作原理.avi 17.web集成-jsp标签权限控制.avi 18.web集成-登出操作.avi 19.spring集成-项目准备.avi 20.spring集成-shiro配置.avi 21.spring集成-登录操作....
Apache Shiro 是目前使用率较高的一个 Java 安全框架。本视频基于 Shiro 的新版本 ...2.Shiro 集成 Web 具体使用 3.Shiro 标签使用 4.Shiro 会话机 5.自定义 Realm 第五章 加密 1.shiro 加密解密 2.shiro 加密应用
shiro+redis作为认证授权服务 oaa,提供为网关feign接口,用来验证权限 。 方案二: zuul作为网关,具备熔断,负载,统一操作日志。整合shiro+redis为网关进行认证权限拦截,过滤器统一异常捕获 ; 两种网关底层实现...
第一讲了解shiro(什么是shiro、shiro的结构体系、核心功能、shiro的架构、shiro的工作流程、RBAC模型),第二讲 用户认证和授权(demo练习),第三讲 JdbcRealm及认证策略,第四讲 与Web集成(shiro+SpringMVC),...
这是一个示例项目,用于将Web应用程序与和集成 该项目通过开放源代码。 制作说明 该项目需要Maven 3.0.4进行构建。 运行以下命令: > mvn install 要求 开设一个。 获取您的API密钥并将文件放置在安全的位置。 请...
shiro文档张开涛,文档详细,层次分明。Shiro 简介、身份验证、授权、INI 配置、编码/加密、Realm 及相关对象、与 Web 集成.....