zoukankan      html  css  js  c++  java
  • Shiro集成Web

    Shiro不仅可以集成到web中,也可以集成Spring。

    1、在WEB中添加Shrio支持

    2、WEB中INI配置

     3、JSP/GSP标签

    在WEB中添加Shrio支持

    如果要想在web中使用Shrio,需要在web.xml文件中添加一个监听器和过滤器。

    <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>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

    在默认情况下,Shrio会从/WEB-INF/shiro.ini和classpath两个目录下去寻找ini配置文件。如果需要指定特定的位置,也可以通过添加context-parm的方式指定位置。

    <context-param>
        <param-name>shiroConfigLocations</param-name>
        <param-value>YOUR_RESOURCE_LOCATION_HERE</param-value>
    </context-param>

    由于一般情况下,我们利用shiro来进行权限控制的时候,都希望让Shiro来拦截所有的请求,所以,最好是把shiro的mapping放在最前面。

    配置监听器和过滤器之后,在启动的时候,EnviromentLoaderListener会实例化一个WebEnvironment实例,其中包括SecurityManager。并且是绑定到当前Servlet上下文的。如果需要获取当前的WebEnvironment的话,可以通过WebUtil.getRequiredWebEnvironment(servletContext)。

    WEB中INI配置

    在ini配置文件中,除了有[mian] [users] [roles]之外,还有一个节,叫做:[urls]

    在[urls]中,你可以配置点对点的过滤器,提供了更加灵活的功能。

    格式:

    _URL_Ant_Path_Expression_ = _Path_Specific_Filter_Chain_

    例子:

    ...
    [urls]
    
    /index.html = anon
    /user/create = anon
    /user/** = authc
    /admin/** = authc, roles[administrator]
    /rest/** = authc, rest
    /remoting/rpc/** = authc, perms["remote:invoke"]

    其中,左边表示的请求的资源路径,以当前的上下文的根目录开始,也就是HttpServletRequest.getContextPath()的值。

    两个星号代表后面是什么都可以,也可以还有几层路径,也就是说:

    /user/name/age这个路径也会被/user/**过滤。但是需要注意的是,这些请求的配置是有先后顺序的,第一个匹配的会被调用。

    等号右边的表示过滤器链。这些过滤器的名字表示的是在[main]中定义的过滤器,Shiro也自带了一些可以直接使用的过滤器。

    在每个过滤器中还可以通过中括号来添加选项,过滤器的唤醒也是跟定义的顺序一样。

    自动启动的过滤器

    在Shrio自动启动的过滤器的名字都配置在org.apache.shiro.web.filter.mgt.DefaultFilter 这个枚举类中。

    名字 作用
    anon org.apache.shiro.web.filter.authc.AnonymousFilter 不进行任何的安全check, 允许是一个匿名用户
    authc org.apache.shiro.web.filter.authc.FormAuthenticationFilter 需要是认证过的,否则的话重定向loginUrl中定义的路径 
    authcBasic org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter  需要是认证过的,如果没有的话则弹出登陆的对话框
    logout org.apache.shiro.web.filter.authc.LogoutFilter  会立刻退出,并且重定向到redirectUrl中定义的url
    noSessionCreation org.apache.shiro.web.filter.session.NoSessionCreationFilter 不创建session 
    perms org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter  是否有指定的权限
    port org.apache.shiro.web.filter.authz.PortFilter 需要是通过指定的端口访问,如果不是的话则通过指定的port访问 
    rest org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter

    会自动根据请求的方法构建一个权限字符串来验证是否有这个权限,head->read get->read put->update post->create 等等。 

    roles org.apache.shiro.web.filter.authz.RolesAuthorizationFilter  如果有指定的角色
    ssl org.apache.shiro.web.filter.authz.SslFilter  只有是通过https访问的,否则自动跳转到https的443端口
    user org.apache.shiro.web.filter.authc.UserFilter 如果是登陆了或者记住了用户则可以访问,否则重定向到login.url 

    他们分别可以实现不同的功能,比如:anon可以用来在不执行任何安全检测的前提下执行某些操作。

    [main]
    ...
    # Notice how we didn't define the class for the FormAuthenticationFilter ('authc') - it is instantiated and available already:
    authc.loginUrl = /login.jsp
    ...
    
    [urls]
    ...
    # make sure the end-user is authenticated.  If not, redirect to the 'authc.loginUrl' above,
    # and after successful authentication, redirect them back to the original account page they
    # were trying to view:
    /account/** = authc
    ...

     如果要想让某个过滤器无效的话,最简单的方式是把他们移除出过滤器链,但是,还有一种不该表过滤器链的方式,那就是通过他们从OncePerRequestFilter中继承的功能,设置enable为false。

    [main]
    ...
    # configure Shiro's default 'ssl' filter to be disabled while testing:
    ssl.enabled = false
    
    [urls]
    ...
    /some/path = ssl, authc
    /another/path = ssl, roles[admin]
    ...

    基于表单的登陆

    在web中,authc默认是一个FormAuthenticationFilter,它支持从表单中读取登陆信息和记住我。

    但是用户名需要是username,密码需要是password,记住我需要是一个rememberMe的checkbox。

    <form ...>
    
       Username: <input type="text" name="username"/> <br/>
       Password: <input type="password" name="password"/>
        ...
       <input type="checkbox" name="rememberMe" value="true"/>Remember Me?
       ...
    </form>

    如果不想使用默认的名字,则可以通过在ini中配置。

    [main]
    ...
    authc.loginUrl = /whatever.jsp
    authc.usernameParam = somethingOtherThanUsername
    authc.passwordParam = somethingOtherThanPassword
    authc.rememberMeParam = somethingOtherThanRememberMe
    ...

    JSP/GSP标签

    如果要在JSP页面中使用Shiro的标签的话,则需要shiro-web.jar的支持。还需要添加下面的taglib。

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

    <shiro:guest>:只有当当前用户是游客的时候,才会显示标签中的内容。

    <shiro:user>:只有当当前用户是登陆过的或记住了,才会显示标签中的内容,和guest相反。

    <shiro:authenticated>:只有当是认证过的,才会显示当前标签中中的内容

    <shiro:notAuthenticated>:只有当是没有认证过的,才会显示当前标签中中的内容跟authenticated相反。

    <shiro:principal>:会打印出当前用户的用户名。

    <shiro:principal type="类型">:会按指定类型打印出当前用户的用户名。

    <shiro:principal propertype="名字">:打印用户中的某个属性。

    <shiro:hasRole>:只有当当前用户有这个角色的时候才会显示标签内的内容。

    <shiro:lacksRole name="角色名">:只有当当前用户没有这个角色的时候才会显示标签内的内容。

    <shiro:hasAnyRole name="角色1,角色2...">:只有当当前用户有其中某个角色的时候才会显示标签内的内容。

    <shiro:hasPermission>:只有当当前用户有这个权限的时候才会显示标签内的内容。

    <shiro:lacksPermission name="角色名">:只有当当前用户没有这个权限的时候才会显示标签内的内容。

     

     下面就通过一个简单的例子,来演示下在web中的权限控制。

    首先编写ini文件

    [main]
    authc.loginUrl=/login.jsp
    [users]
    fuwh=123456
    
    [urls]
    /login.jsp=anon
    /static/**=authc

    其中,/login.jsp是不用登陆就可以访问的,/static/目录下的所有资源访问都需要是登陆状态,

    如果没有登陆的话,则会跳转到login.jsp页面。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">
        用户名:<input type="text" name="username"/><br/>&nbsp;码:<input type="password" name="password"/><br/>
        <input type="checkbox" name="rememberMe" value="true"/>记住我&nbsp;&nbsp;
        <input type="submit" value="登陆">
    </form>
    </body>
    </html>

    编写LoginServlet

    package com.fuwh.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{
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // TODO Auto-generated method stub
            System.out.println("doGet");
    //        this.doPost(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // TODO Auto-generated method stub
            System.out.println("doPost");
            Subject subject=SecurityUtils.getSubject();
            UsernamePasswordToken token=new UsernamePasswordToken(req.getParameter("username"),req.getParameter("password"));
            try {
                subject.login(token);
                resp.sendRedirect(req.getContextPath()+"/static/success.jsp");
            } catch (Exception e) {
                // TODO: handle exception
                resp.sendRedirect(req.getContextPath()+"/static/success.jsp");
            }
            
        }
    
    }

    在这个servlet中,不管登陆成功都跳转到/static/success.jsp页面,但是如果登陆不成功的话,则会被shiro拦截,跳转到login.jsp页面去了。

    点此查看源码:https://github.com/oukafu/shiro

  • 相关阅读:
    在 docker 容器中捕获信号
    python入门二维码生成
    SSH 端口转发
    Python之模块与包
    滑块验证demo示例
    上下界网络流初探
    大整数模板
    计算几何模板
    关于差分约束系统的脑洞
    并查集,以及可拆分并查集
  • 原文地址:https://www.cnblogs.com/zerotomax/p/7440440.html
Copyright © 2011-2022 走看看