`
李大宝
  • 浏览: 14618 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

shiro-集成web

阅读更多

前面两节内容介绍了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这个就不多说了,结合上面两个就知道了。

 

  • 大小: 38.3 KB
分享到:
评论

相关推荐

    shiro-1.7.1.zip

    2. **shiro-web-1.7.1.jar**: 这个模块专门用于Web应用的安全性,提供了过滤器(Filter)来拦截HTTP请求,实现登录、登出、权限检查等功能。例如,Shiro的RememberMe服务、Session管理以及CSRF防护等功能都在这个...

    shiro-root-1.2.3-source-release zipa包 和相关jar包

    5. **Web支持**:Shiro可以轻松地集成到Web应用程序中,提供了过滤器来处理HTTP请求,实现认证和授权。 6. **测试支持**:Shiro的API设计简洁,易于单元测试,使得开发者可以在测试环境中快速配置和验证安全性。 ...

    shiro1.7.1.zip

    2. **shiro-web-1.7.1.jar**:这个模块是针对Web环境设计的,提供了Web相关的安全控制,如Filter配置、HTTP请求的拦截处理等,方便在Web应用中集成Shiro。 3. **shiro-lang-1.7.1.jar**:Shiro的语言支持模块,可能...

    SpringMVC-Mybatis-Shiro-redis-master

    【标题】"SpringMVC-Mybatis-Shiro-redis-master" 涉及的是一个集成框架项目,这个项目集成了四个关键的技术组件:SpringMVC、MyBatis、Shiro和Redis。这些技术在现代Java Web开发中扮演着重要角色。 **SpringMVC**...

    shiro-web-master.zip

    "shiro-web-master"暗示了我们还会接触到如何在Spring Boot或其它Web框架中集成Shiro。这通常涉及配置Shiro过滤器链,如`authc`(认证过滤器)、`perms`(权限过滤器)等,以实现URL级别的访问控制。 7. **实战...

    shiro源码(shiro-root-1.8.0-source-release.zip)

    在Web应用中,Shiro提供了一系列过滤器,如RememberMeFilter、LoginFilter、UnauthorizedFilter等,它们可以直接集成到Servlet容器中,实现登录、权限检查等功能。 6. **Remember Me**: Shiro的Remember Me服务...

    shiro-web api

    shiro web集成方向api,chm格式的。

    SpringMVC-Mybatis-Shiro-redis

    《SpringMVC-Mybatis-Shiro-Redis:构建安全高效的Web应用》 在现代Web开发中,构建一个高效且安全的后端系统是至关重要的。本文将深入探讨一个基于SpringMVC、Mybatis、Shiro和Redis的Web应用架构,这四个组件共同...

    shiro-root-1.2.2-source-release.zip

    - `web` 模块提供了与Web应用程序集成的支持。 - `examples` 包含了各种示例应用,展示了如何在实际项目中使用Shiro。 - `tests` 目录下的源码可以作为学习Shiro内部实现的参考。 5. **使用Shiro** 开发者可以...

    shiro-all jar

    8. **org.apache.shiro.web**: 针对Web应用的安全管理,提供过滤器、控制器等功能,易于与Servlet容器集成。 9. **org.apache.shiro.config**: 配置管理,支持XML和Java配置API,方便设置Shiro的行为。 10. **org....

    shiro-all-1.2.3.jar

    6. 测试:运行应用,进行登录、权限控制等功能的测试,确保Shiro集成正确并按预期工作。 "使用说明.txt" 文件可能包含如何在项目中引入和配置"shiro-all-1.2.3.jar"的详细指南,包括如何设置Shiro配置文件,以及...

    shiro-redis集成的spring的web项目

    在IT行业中,Shiro、Redis和Spring的集成是构建高效、安全Web应用的常见实践。本项目是一个将Apache Shiro与Redis缓存系统整合到Spring框架中的实例,旨在提升应用程序的安全性和性能。以下是对这个项目及其相关技术...

    shiro项目基本运行架包以及全部的架包shiro-all.jar

    5. **Web支持**:Shiro提供了集成到Web应用的特性,如过滤器(Filter)来处理HTTP请求,实现登录、权限检查等功能。 6. **测试支持**:Shiro提供了一些测试工具,方便开发者在单元测试和集成测试中验证安全性。 ...

    shiro1.7.1全包修补漏洞.rar

    5. **shiro-web-1.7.1.jar**: Shiro的Web支持模块,用于处理HTTP请求的安全性。它提供了过滤器来处理如登录、登出、权限检查等Web相关的安全需求。 6. **shiro-core-1.7.1.jar**: Shiro的核心库,包含基础的安全...

    shiro-root-1.3.2-source-release

    你提到的 "shiro-root-1.3.2-source-release" 是Apache Shiro 1.3.2版本的源码发布包,其中包含了Shiro的核心实现类以及相关的集成示例。 Shiro 的核心组件包括以下几个部分: 1. **认证**(Authentication):这...

    shiro-cas-1.2.1.jar

    Shiro 能够与任何应用进行集成,无论它是 Web 应用、独立的桌面应用还是分布式服务系统。在本案例中,我们关注的是 Shiro 集成 CAS(Central Authentication Service)的实现,这通常用于实现单点登录(Single Sign-...

    shiro-shiro-root-1.5.3.zip

    5. **Web支持**:Shiro可以方便地与Web应用集成,提供HTTP请求过滤器进行安全控制,同时支持CSRF防护和Session hijacking防护。 6. **缓存管理**:Shiro支持缓存策略,提高授权和会话管理的效率,减少数据库查询...

    单点登录sso-shiro-cas-maven

    -- Shiro's main business-tier object for web-enabled applications --&gt; &lt;bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"&gt; ...

    shiro jar包及源码下载

    5. **Web支持**:Shiro提供了一系列过滤器,可以直接集成到Servlet容器中,实现Web应用的安全控制,如登录检查、权限验证等。 6. **测试支持**:Shiro提供了安全测试工具,使得在单元测试和集成测试中模拟用户身份...

    shiro-root-1.32-source-release

    5. **Web 支持**:Shiro 提供了 Filter 方式集成到 Web 应用中,如 SecurityManagerFilter、LoginFilter 等,使得在 Web 开发中实现安全控制变得简单。 6. **核心组件**:在 `core` 文件夹中,包含了 Shiro 的核心...

Global site tag (gtag.js) - Google Analytics