shiro如何去掉弹出提示框登录_Servlet整合Shiro(四)

Servlet整合Shiro去除登录提示框详解
本文详细介绍了如何在Servlet中整合Shiro以去掉登录提示框,涉及Shiro配置文件的四大板块:[main]、[users]、[roles]、[urls],并解析了各部分的作用。讲解了Shiro的拦截器机制和具体使用,包括配置url及拦截器的关系。此外,还阐述了Servlet整合Shiro的步骤,从添加依赖、配置web.xml到编写后台控制和前端页面,以及详细的验证过程,展示了如何实现权限控制。
部署运行你感兴趣的模型镜像

戒色诗: 二八佳人体似酥,腰间仗剑斩凡夫。虽然不见人头落,暗里教君骨髓枯。

一. Shiro 配置文件的四大部分

在 shiro.ini 这个配置文件中, 有四个部分, [main], [users],[roles], 还有一个 [urls], 前面三个部分,我们都讲解了,只剩下一个 urls。这儿进行讲解一下。

一. 一  [main] 部分

提供了对根对象securityManager及其依赖对象的配置。

如,前面的 jdbc 配置 和策略配置。

[main]#配置数据源dataSource=com.mchange.v2.c3p0.ComboPooledDataSource#配置数据库的信息dataSource.driverClass=com.mysql.jdbc.DriverdataSource.jdbcUrl=jdbc:mysql://localhost:3306/shiro?characterEncoding=utf8dataSource.user=rootdataSource.password=abc123#配置 realmjdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm#配置数据源jdbcRealm.dataSource=$dataSource#注入多个realm 到securityManager里面securityManager.realm=$jdbcRealm#配置验证器authenticationStrategy=org.apache.shiro.authc.pam.FirstSuccessfulStrategysecurityManager.authenticator.authenticationStrategy=$authenticationStrategy

在与 Servlet 进行整合时, [main] 部分也常常添加 如下两个部分:

authc.loginUrl=/User/toLoginroles.unauthorizedUrl=/NoPermission/NoPermissionperms.unauthorizedUrl=/NoPermission/NoPermission

authc.loginUrl=/User/toLogin, 是配置没有通过认证时,跳转的页面, 通常是 登录页面

roles.unauthorizedUrl=/NoPermission/NoPermission 是没有配置要求的角色时跳转的页面, 通常是权限不足页面

perms.unauthorizedUrl=/NoPermission/NoPermission 是没有当前要求的权限时跳转的页面, 通常是权限不足页面。

一.二  [users] 部分

主要是配置用户的信息, 用户名=密码,角色1,角色2 ... 角色可以省略。

[users]#用户名=密码,角色1,角色2yuejl=1234,role1,role3yuezl=1234,role2

一.三  [roles] 部分

主要是配置角色与权限的信息, 角色=权限1,权限2

[roles]role1=user:add,user:deleterole2=user:*role3=user:select

一.四  [urls] 部分

配置 url 及相应的拦截器之间的关系, url=拦截器1[参数],拦截器2[参数]

[urls]/static/**=anon/User/toLogin=anon/User/login=anon/Main/toMain=authc/User/add=authc,perms["user:add"]/User/update=authc,perms["user:update"]/User/select=authc,perms["user:select"]/User/delete=authc,perms["user:delete"]

即 访问 /static/ 路径时, 被 anon 拦截器拦截,

访问 /Main/toMain 路径时,被 authc 拦截器拦截

访问 /User/add 路径时, 被authc 拦截器拦截,并且被拦截器 perms 拦截器 进行拦截

其中, anon, authc,perms 都是拦截器的别名缩写,分别代表着不同的功能。

二.  Shiro 的拦截器

关于拦截器的详细使用,可以看 张开涛前辈写得文章:  第八章 拦截器机制——《跟我学Shiro》

Shiro 为了方便 认证和授权,提供了好多默认拦截器。

二.一  拦截器定义位置

拦截器 被定义在 org.apache.shiro.web.filter.mgt.DefaultFilter 类下。

 public enum DefaultFilter {   anon(AnonymousFilter.class),    authc(FormAuthenticationFilter.class),    authcBasic(BasicHttpAuthenticationFilter.class),    logout(LogoutFilter.class),    noSessionCreation(NoSessionCreationFilter.class),    perms(PermissionsAuthorizationFilter.class),    port(PortFilter.class),    rest(HttpMethodPermissionFilter.class),   roles(RolesAuthorizationFilter.class),   ssl(SslFilter.class),   user(UserFilter.class);... }

前面的 anon,authc 就是别名缩写, AnonymousFilter,FormAuthenticationFilter 是其对应的拦截器类。

二.二 各个拦截器的意义

默认拦截器名对应类说明
认证有关的
authcorg.apache.shiro.web.filter.authc.FormAuthenticationFilter基于表单的拦截器;如“/**=authc”,如果没有登录会跳到相应的登录页面登录;主要属性:usernameParam:表单提交的用户名参数名( username);passwordParam:表单提交的密码参数名(password);rememberMeParam:表单提交的密码参数名(rememberMe); loginUrl:登录页面地址(/login.jsp);successUrl:登录成功后的默认重定向地址; failureKeyAttribute:登录失败后错误信息存储key( shiroLoginFailure);
anonorg.apache.shiro.web.filter.authc.AnonymousFilter匿名拦截器,即不需要登录即可访问;一般用于静态资源过滤;示例“/static/**=anon”
authcBasicorg.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilterBasic HTTP身份验证拦截器,主要属性:applicationName:弹出登录框显示的信息(application);
logoutorg.apache.shiro.web.filter.authc.LogoutFilter退出拦截器,主要属性:redirectUrl:退出成功后重定向的地址(/);示例“/logout=logout”
userorg.apache.shiro.web.filter.authc.UserFilter用户拦截器,用户已经身份验证/记住我登录的都可;示例“/**=user”
授权有关的
rolesorg.apache.shiro.web.filter.authz.RolesAuthorizationFilter角色授权拦截器,验证用户是否拥有所有角色;主要属性:loginUrl:登录页面地址(/login.jsp);unauthorizedUrl:未授权后重定向的地址;示例“/admin/**=roles[admin]”
permsorg.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter权限授权拦截器,验证用户是否拥有所有权限;属性和roles一样;示例“/user/**=perms["user:create"]”
portorg.apache.shiro.web.filter.authz.PortFilter端口拦截器,主要属性:port(80):可以通过的端口;示例“/test= port[80]”,如果用户访问该页面是非80, 将自动将请求端口改为80并重定向到该80端口,其他路径/参数等都一样
restorg.apache.shiro.web.filter.authz.HttpMethodPermissionFilterrest风格拦截器,自动根据请求方法构建权限字符串(GET=read, POST=create,PUT=update,DELETE=delete,HEAD=read,TRACE=read,OPTIONS=read, MKCOL=create)构建权限字符串;示例“/users=rest[user]”,会自动拼出“user:read,user:create,user:update,user:delete”权限字符串进行权限匹配(所有都得匹配,isPermittedAll);
sslorg.apache.shiro.web.filter.authz.SslFilterSSL拦截器,只有请求协议是https才能通过;否则自动跳转会https端口(443);其他和port拦截器一样;
其他
noSessionCreationorg.apache.shiro.web.filter.session.NoSessionCreationFilter不创建会话拦截器,调用 subject.getSession(false)不会有什么问题,但是如果 subject.getSession(true)将抛出 DisabledSessionException异常;

可以通过 配置文件 来做一个简单的 小Demo. 由于还没有学习自定义Realm, 故先用配置文件的形式获取数据。

三.  Servlet 整合 Shiro

三.一  添加依赖

需要添加 关于 shiro 的依赖,日志的依赖,还有tomcat 的依赖。用到了 json,需要添加 json的依赖。

                        javax.servlet.jsp            javax.servlet.jsp-api            2.3.1            provided                            javax.servlet            javax.servlet-api            3.1.0            provided                                    javax.servlet            jstl            1.2                            taglibs            standard            1.1.2                          org.apache.shiro        shiro-all        1.2.2            junit        junit        4.12            org.slf4j        slf4j-log4j12        1.7.25            commons-logging        commons-logging        1.2              net.sf.json-lib            json-lib            2.4                            org.apache.commons            commons-lang3            3.1                            commons-collections            commons-collections            3.2.2                                                org.apache.maven.plugins                maven-compiler-plugin                3.1                                    1.8                    1.8                                                        org.apache.tomcat.maven                                tomcat7-maven-plugin                2.2                                    8080                    /Shiro_Web                    UTF-8                                    

三.二 配置 web.xml

需要配置监听器,配置文件的路径,添加过滤器。

      org.apache.shiro.web.env.EnvironmentLoaderListener   shiroEnvironmentClass   org.apache.shiro.web.env.IniWebEnvironment            shiroConfigLocations        classpath:shiro.ini          ShiroFilter    org.apache.shiro.web.servlet.ShiroFilter        ShiroFilter    /*  

有的教程说,1.2版本以上不用配置过滤器,但没有配置时,老蝴蝶这项目运行报错,创建securityManager 报错,添加上就没有问题了。故老蝴蝶这儿添加上shiro 过滤器。

三.三 编写配置文件  shiro.ini

[main]#没有登录时,跳转到登录的路径authc.loginUrl=/User/toLogin#跳转到权限不足的路径roles.unauthorizedUrl=/NoPermission/NoPermissionperms.unauthorizedUrl=/NoPermission/NoPermission# 配置用户的信息[users]#用户名=密码,角色1,角色2yuejl=1234,role1,role3yuezl=1234,role2# 定义角色的信息, 角色,权限, *表示全部的权限[roles]role1=user:add,user:deleterole2=user:*role3=user:select[urls]#静态页面可以访问/static/**=anon#跳转到登录页面和登录方法可以访问/User/toLogin=anon/User/login=anon#跳转到主页,需要认证/Main/toMain=authc#执行方法,不仅需要认证,还需要有相应的方法/User/add=authc,perms["user:add"]/User/update=authc,perms["user:update"]/User/select=authc,perms["user:select"]/User/delete=authc,perms["user:delete"]#退出登录/User/logout=logout

由于配置文件中,用的是 key=value, 所以在访问路径时,不能用以前的 /User?jsp=toLogin, 和 /User?method=login 了。

BaseServlet 不能使用了, 需要用原始的一个方法,一个Servlet的形式了。

yuejl 没有修改的权限, yuezl 具有全部的权限。

三.四  编写后台控制

后台类结构:

f9146c93c7843214ff137e720707bdd1.png

三.四.一  跳转到登录的类

@WebServlet("/User/toLogin")public class UserToLoginServlet extends HttpServlet{private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        req.getRequestDispatcher("/WEB-INF/pages/login.jsp").forward(req, resp);        }}

三.四.二  登录类

@WebServlet("/User/login")public class UserLoginServlet extends HttpServlet{private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        //找到相应的Subject        Subject subject=SecurityUtils.getSubject();                UsernamePasswordToken token=new UsernamePasswordToken(req.getParameter("code"),                req.getParameter("password"));        try{            subject.login(token);            boolean2Json(resp, true);        }catch(Exception e){            //代码为001,表示用户名或者密码错误             map2Json(resp,"001");        }}/** * 将状态返回到前台,通常是添加,删除,更新的操作,如果错误,则传入错误代码。 * @param o * @param exclueds */public void map2Json(HttpServletResponse resp,String ... code){        //指定哪些属性不需要转json        JSONObject objMap=new JSONObject();        if(code==null||code.length<1){            objMap.put("status",true);        }else{            objMap.put("status",false);            objMap.put("error_code",code[0]);        }        resp.setContentType("text/json;charset=utf-8");        try {            resp.getWriter().print(objMap.toString());        } catch (IOException e) {            e.printStackTrace();        }}/** * 传入是否成功,只返回状态 * @param o * @param exclueds */public void boolean2Json(HttpServletResponse resp,boolean flag){        //指定哪些属性不需要转json        JSONObject objMap=new JSONObject();        objMap.put("status",true);        objMap.put("flag",flag);        resp.setContentType("text/json;charset=utf-8");        try {            resp.getWriter().print(objMap.toString());        } catch (IOException e) {            e.printStackTrace();        }}}

注意,这两个Json 转换的方法是通用的,每一个需要转换的类里面都有,避免代码过多,老蝴蝶这不重复写了。

三.四.三 登录成功后跳转到主页

@WebServlet("/Main/toMain")public class MainServlet extends HttpServlet{private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        req.getRequestDispatcher("/WEB-INF/pages/main.jsp").forward(req, resp);        }}

三.四.四  退出方法

@WebServlet("/User/logout")public class UserLoginOutServlet extends HttpServlet{private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        Subject subject=SecurityUtils.getSubject();        //退出登录        subject.logout();        req.getRequestDispatcher("/WEB-INF/pages/login.jsp").forward(req, resp);}}

三.四.五 跳转到员工页面

@WebServlet("/User/toList")public class UserToListServlet extends HttpServlet{private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        req.getRequestDispatcher("/WEB-INF/pages/user.jsp").forward(req, resp);        }}

三.四.六 员工添加

@WebServlet("/User/add")public class UserAddServlet extends HttpServlet{private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        System.out.println("执行添加的方法");        boolean2Json(resp, true);}...//json 转换的方法,具体见登录方法}

三.四.七 员工修改

@WebServlet("/User/update")public class UserUpdateServlet extends HttpServlet{private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        System.out.println("执行修改的方法");        boolean2Json(resp, true);}}

三.四.八 员工删除

@WebServlet("/User/delete")public class UserDeleteServlet extends HttpServlet{private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        System.out.println("执行删除的方法");        boolean2Json(resp, true);}}

三.四.九 员工查询

@WebServlet("/User/select")public class UserSelectServlet extends HttpServlet{private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        System.out.println("执行查询的方法");        boolean2Json(resp, true);}}

三.五 编写前端静态页面

结构目录如下所示:

b1916cbd4dd5c4347ba9d81419fe659c.png

三.五.一   编写 index.jsp

谢谢您访问我,我是两个蝴蝶飞

三.五.二 编写登录页面 login.jsp

两个蝴蝶飞登录页面

 
用户名:
name="code" value=""/>
密码:
name="password"/>

ajax 方法,进行提交跳转

$(function(){        $("#submit").click(function(){            var code=$("#code").val();            var password=$("#password").val();                        var info=new Object();            //传入进去,员工的id编号            info.code=code;            info.password=password;                        $.post("${pageContext.request.contextPath}/User/login",info,function(data){                if(data.status){                    alert("登录成功");                    window.location.href="${pageContext.request.contextPath}/Main/toMain";                }else{                    if(data.error_code=="001"){                        alert("用户名或者密码错误");                    }                }            })                    })        })

三.五.三  主页  main.jsp

进入到主页          欢迎[]登录,退出         

三.五.四  权限不足页面  noPrivilege.jsp

抱歉,您没有权限访问!!!

三.五.五 员工按钮显示页面  user.jsp

是否有查询权限: 有查询权限是否有添加权限: 有添加权限是否有修改权限: 有修改权限是否有删除权限: 有删除权限

shiro:user, shiro:hasPermission 是shiro 提供的标签库, 通过判断是否有权限,来显示页面元素的显示和隐藏。

注意, 不要忘记引用 shiro 标签库

75ac15e351fd46ba7e05ac17fc8dddd5.png

关于 shiro 标签库的使用,可以看 第九章 JSP标签——《跟我学Shiro》

记住常用的 shiro:user, shiro:hasPermission 即可。

三.六 验证

三.六.一 用户 yuejl 验证

输入网址: http://localhost:8080/Shiro_Web/

填写账号 yuejl, 密码是 123456, 错误的密码

349c267639fc0e22ec802938f079858a.png

填写账号 yuejl, 密码是 1234, 正确的密码

979c9f7a2aa97e445c817934bc5d3e4f.png

fe05c431b2e4379a0dc785b7b1bd5892.png

员工yuejl 正常登录, 输入网址,跳转到员工的界面

http://localhost:8080/Shiro_Web/User/toList

员工yuejl 没有修改的权限,故修改那一块的元素不显示

8f455ca57a05e2c706c8e162946f65b3.png

手动输入网址,看是否可以访问:

输入添加的网址:  http://localhost:8080/Shiro_Web/User/add

d366ff06c4a689a29977b237273bf48e.png

员工具有添加的权限,故可以执行添加的操作。

输入修改的网址,http://localhost:8080/Shiro_Web/User/update

799e97b84df006363736d929bf942a72.png

员工不具有修改的权限,故不可以执行修改的操作,会显示权限不足。

点击退出,退出之后, 输入刚才的 添加的那个网址,会跳转到登录的页面

d5d8e9e412fc4f5e7c4b31fbf2482bf7.png

三.六.二  用户 yuezl 验证

前面的测试,与yuejl 一样。

yuezl 具有修改的权限:

http://localhost:8080/Shiro_Web/User/toList

706efaba9766bc39e62fe4f3b29596f8.png

当手动输入修改的网址时:   http://localhost:8080/Shiro_Web/User/update

4eb199b2b8258451bd1447d0c35aedb3.png

Servlet 整合 Shiro, 控制权限成功。

本章节代码链接为:

链接:https://pan.baidu.com/s/1dMQkpcxU04WKLnIdbsm-Aw 提取码:kmji

谢谢您的观看,我是两个蝴蝶飞, 如果喜欢,请关注我,再次感谢 !!!

您可能感兴趣的与本文相关的镜像

Langchain-Chatchat

Langchain-Chatchat

AI应用
Langchain

Langchain-Chatchat 是一个基于 ChatGLM 等大语言模型和 Langchain 应用框架实现的开源项目,旨在构建一个可以离线部署的本地知识库问答系统。它通过检索增强生成 (RAG) 的方法,让用户能够以自然语言与本地文件、数据库或搜索引擎进行交互,并支持多种大模型和向量数据库的集成,以及提供 WebUI 和 API 服务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值