shiro启动之后页面访问不了_java:shiro入门——4
【7】測試
【7.1】啟動
點擊apply然后點擊OK
【7.2】登錄過濾
訪問http://localhost:8080/platform/home的時候,會被
【7.3】角色過濾
使用“admin”用戶登錄,密碼:123
根據SecurityServiceImpl我們可以知道使用admin賬號
登錄成功之后:
此時點擊“列表”,因為當前admin用戶是有admin角色
所有可以正常訪問
點擊“添加”,因為當前admin用戶是沒有order:add的資源
所以回401
【7.4】資源過濾
點擊“退出”
使用“jay”用戶登錄,密碼為123
點擊“添加”
因為SecurityServiceImpl中為jay用戶添加如下的資源
點擊“添加”之后正常訪問
點擊“列表”之后,因為“jay”用戶滿意“admin”角色,所以訪問受限
4、web項目授權
前面我們學習了基于ini文件配置方式來完成授權,下面我們來看下其他2種方式的授權
【1】基于代碼
【1.1】登錄相關
【1.2】角色相關
【1.3】資源相關
【1.4】案例
【1.4.1】創建項目
拷貝shiro-day01-07web新建shiro-day01-08web-java
【1.4.2】修改shiro.ini
#聲明自定義的realm,且為安全管理器指定realms[main]definitionRealm=com.itheima.shiro.realm.DefinitionRealmsecurityManager.realms=$definitionRealm#用戶退出后跳轉指定JSP頁面logout.redirectUrl=/login.jsp#若沒有登錄,則被authc過濾器重定向到login.jsp頁面authc.loginUrl = /login.jsp[urls]/login=anon#發送/home請求需要先登錄#/home= authc#發送/order/list請求需要先登錄#/order-list = roles[admin]#提交代碼需要order:add權限#/order-add = perms["order:add"]#更新代碼需要order:del權限#/order-del = perms["order:del"]#發送退出請求則用退出過濾器/logout = logout【1.4.3】登錄相關
修改HomeServlet的doPost方法
package com.itheima.shiro.web;import org.apache.shiro.SecurityUtils;import org.apache.shiro.subject.Subject;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** * @Description:系統home頁面 */@WebServlet(urlPatterns = "/home")public class HomeServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //通過subjectd對象去判斷是否登錄 Subject subject = SecurityUtils.getSubject(); boolean flag = subject.isAuthenticated(); if (flag){ resp.sendRedirect("home.jsp"); }else { req.getRequestDispatcher("/login").forward(req, resp); } }}訪問http://localhost:8080/platform/home 進行debug
此時我們通過subject.isAuthenticated()判斷是否登錄,如果登錄則重定向到home.jsp,如果沒有登錄則轉發到/login對應的servlet
【1.4.4】角色相關
修改OrderListServlet的doPost方法,判斷是否有admin角色,如果有則轉發order-list.jsp,沒有則轉發/login
package com.itheima.shiro.web;import org.apache.shiro.SecurityUtils;import org.apache.shiro.subject.Subject;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** * @Description:訂單列表 */@WebServlet(urlPatterns = "/order-list")public class OrderListServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Subject subject = SecurityUtils.getSubject(); //判斷當前角色 boolean flag = subject.hasRole("admin"); if (flag){ req.getRequestDispatcher("order-list.jsp").forward(req, resp); }else { req.getRequestDispatcher("/login").forward(req, resp); } }}訪問http://localhost:8080/platform/order-list
因為此時我未登錄,也就是說當前沒有admin角色,這是通過subject.hasRole("admin")返回未false
【1.4.5】資源相關
修改OrderAddServlet
package com.itheima.shiro.web;import org.apache.shiro.SecurityUtils;import org.apache.shiro.subject.Subject;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** * @Description:添加頁碼 */@WebServlet(urlPatterns = "/order-add")public class OrderAddServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Subject subject = SecurityUtils.getSubject(); //判斷是否有對應資源 boolean flag = subject.isPermitted("order:add"); if (flag){ req.getRequestDispatcher("order-add.jsp").forward(req, resp); }else { req.getRequestDispatcher("/login").forward(req, resp); } }}訪問http://localhost:8080/platform/order-add
因為此時我未登錄,也就是說當前沒有order:add資源,通過 subject.isPermitted("order:add")返回未false
【2】基于Jsp標簽
【2.1】使用方式
Shiro提供了一套JSP標簽庫來實現頁面級的授權控制, 在使用Shiro標簽庫前,首先需要在JSP引入shiro標簽:
【2.2】相關標簽
【2.3】案例
【2.3.1】新建項目
拷貝shiro-day01-08web-java新建shiro-day01-09web-jsp-taglib項目
【2.3.2】修改home.jsp
退出 列表 添加
【2.3.3】測試
訪問http://localhost:8080/platform/login
使用admin/123登錄
這個時候我們只能看見“列表”,看不見“添加”,點擊“退出”
使用jay/123登錄
這個時候我們只能看見“添加”,看不見“列表”,點擊“退出”
需要注意的是,這里只是頁面是否顯示內容,不能防止盜鏈的發生
第五章 Springboot集成Shiro
1、技術棧
主框架:springboot
響應層:springMVC
持久層:mybatis
事務控制:jta
前端技術:easyui
2、數據庫設計
【1】數據庫圖解
sh_user:用戶表,一個用戶可以有多個角色
sh_role:角色表,一個角色可以有多個資源
sh_resource:資源表
sh_user_role:用戶角色中間表
sh_role_resource:角色資源中間表
【2】數據庫腳本
sh_user
CREATE TABLE `sh_user` ( `ID` varchar(36) NOT NULL COMMENT '主鍵', `LOGIN_NAME` varchar(36) DEFAULT NULL COMMENT '登錄名稱', `REAL_NAME` varchar(36) DEFAULT NULL COMMENT '真實姓名', `NICK_NAME` varchar(36) DEFAULT NULL COMMENT '昵稱', `PASS_WORD` varchar(150) DEFAULT NULL COMMENT '密碼', `SALT` varchar(36) DEFAULT NULL COMMENT '加密因子', `SEX` int(11) DEFAULT NULL COMMENT '性別', `ZIPCODE` varchar(36) DEFAULT NULL COMMENT '郵箱', `ADDRESS` varchar(36) DEFAULT NULL COMMENT '地址', `TEL` varchar(36) DEFAULT NULL COMMENT '固定電話', `MOBIL` varchar(36) DEFAULT NULL COMMENT '電話', `EMAIL` varchar(36) DEFAULT NULL COMMENT '郵箱', `DUTIES` varchar(36) DEFAULT NULL COMMENT '職務', `SORT_NO` int(11) DEFAULT NULL COMMENT '排序', `ENABLE_FLAG` varchar(18) DEFAULT NULL COMMENT '是否有效', PRIMARY KEY (`ID`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='用戶表';sh_role
CREATE TABLE `sh_role` ( `ID` varchar(36) NOT NULL COMMENT '主鍵', `ROLE_NAME` varchar(36) DEFAULT NULL COMMENT '角色名稱', `LABEL` varchar(36) DEFAULT NULL COMMENT '角色標識', `DESCRIPTION` varchar(200) DEFAULT NULL COMMENT '角色描述', `SORT_NO` int(36) DEFAULT NULL COMMENT '排序', `ENABLE_FLAG` varchar(18) DEFAULT NULL COMMENT '是否有效', PRIMARY KEY (`ID`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='用戶角色表';sh_resource
CREATE TABLE `sh_resource` ( `ID` varchar(36) NOT NULL COMMENT '主鍵', `PARENT_ID` varchar(36) DEFAULT NULL COMMENT '父資源', `RESOURCE_NAME` varchar(36) DEFAULT NULL COMMENT '資源名稱', `REQUEST_PATH` varchar(200) DEFAULT NULL COMMENT '資源路徑', `LABEL` varchar(200) DEFAULT NULL COMMENT '資源標簽', `ICON` varchar(20) DEFAULT NULL COMMENT '圖標', `IS_LEAF` varchar(18) DEFAULT NULL COMMENT '是否葉子節點', `RESOURCE_TYPE` varchar(36) DEFAULT NULL COMMENT '資源類型', `SORT_NO` int(11) DEFAULT NULL COMMENT '排序', `DESCRIPTION` varchar(200) DEFAULT NULL COMMENT '描述', `SYSTEM_CODE` varchar(36) DEFAULT NULL COMMENT '系統code', `IS_SYSTEM_ROOT` varchar(18) DEFAULT NULL COMMENT '是否根節點', `ENABLE_FLAG` varchar(18) DEFAULT NULL COMMENT '是否有效', PRIMARY KEY (`ID`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='資源表';sh_role_resource
CREATE TABLE `sh_role_resource` ( `ID` varchar(36) NOT NULL, `ENABLE_FLAG` varchar(18) DEFAULT NULL, `ROLE_ID` varchar(36) DEFAULT NULL, `RESOURCE_ID` varchar(36) DEFAULT NULL, PRIMARY KEY (`ID`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='角色資源表';sh_user_role
CREATE TABLE `sh_user_role` ( `ID` varchar(36) NOT NULL, `ENABLE_FLAG` varchar(18) DEFAULT NULL, `USER_ID` varchar(36) DEFAULT NULL, `ROLE_ID` varchar(36) DEFAULT NULL, PRIMARY KEY (`ID`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='用戶角色表';3、項目骨架
4、ShiroDbRealm定義
【1】圖解
【2】原理分析
(1)、ShiroDbRealmImpl繼承ShiroDbRealm向上繼承AuthorizingRealm,ShiroDbRealmImpl實例化時會創建密碼匹配器HashedCredentialsMatcher實例,HashedCredentialsMatcher指定hash次數與方式,交于AuthenticatingRealm
(2)、調用login方法后,最終調用doGetAuthenticationInfo(AuthenticationToken authcToken)方法,拿到SimpleToken的對象,調用UserBridgeService的查找用戶方法,把ShiroUser對象、密碼和salt交于SimpleAuthenticationInfo去認證
(3)、訪問需要鑒權時,調用doGetAuthorizationInfo(PrincipalCollection principals)方法,然后調用UserBridgeService的授權驗證
【3】核心類代碼
【3.1】ShiroDbRealm
package com.itheima.shiro.core;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import javax.annotation.PostConstruct;/** * * @Description shiro自定義realm */public abstract class ShiroDbRealm extends AuthorizingRealm { /** * @Description 認證 * @param authcToken token對象 * @return */ public abstract AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) ; /** * @Description 鑒權 * @param principals 令牌 * @return */ public abstract AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals); /** * @Description 密碼匹配器 */ @PostConstruct public abstract void initCredentialsMatcher() ;}【3.2】ShiroDbRealmImpl
package com.itheima.shiro.core.impl;import com.itheima.shiro.constant.SuperConstant;import com.itheima.shiro.core.base.ShiroUser;import com.itheima.shiro.core.base.SimpleToken;import com.itheima.shiro.core.ShiroDbRealm;import com.itheima.shiro.core.bridge.UserBridgeService;import com.itheima.shiro.pojo.User;import com.itheima.shiro.utils.BeanConv;import com.itheima.shiro.utils.DigestsUtil;import com.itheima.shiro.utils.EmptyUtil;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.UnknownAccountException;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.util.ByteSource;import org.springframework.beans.factory.annotation.Autowired;/** * @Description:自定義shiro的實現 */public class ShiroDbRealmImpl extends ShiroDbRealm { @Autowired private UserBridgeService userBridgeService; /** * @Description 認證方法 * @param authcToken 校驗傳入令牌 * @return AuthenticationInfo */ @Override public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) { SimpleToken token = (SimpleToken)authcToken; User user = userBridgeService.findUserByLoginName(token.getUsername()); if(EmptyUtil.isNullOrEmpty(user)){ throw new UnknownAccountException("賬號不存在"); } ShiroUser shiroUser = BeanConv.toBean(user, ShiroUser.class); shiroUser.setResourceIds(userBridgeService.findResourcesIdsList(user.getId())); String salt = user.getSalt(); String password = user.getPassWord(); return new SimpleAuthenticationInfo(shiroUser, password, ByteSource.Util.bytes(salt), getName()); } /** * @Description 授權方法 * @param principals SimpleAuthenticationInfo對象第一個參數 * @return */ @Override public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal(); return userBridgeService.getAuthorizationInfo(shiroUser); } /** * @Description 加密方式 */ @Override public void initCredentialsMatcher() { HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(SuperConstant.HASH_ALGORITHM); matcher.setHashIterations(SuperConstant.HASH_INTERATIONS); setCredentialsMatcher(matcher); }}【3.3】SimpleToken
package com.itheima.shiro.core.base;import org.apache.shiro.authc.UsernamePasswordToken;/** * @Description 自定義tooken */public class SimpleToken extends UsernamePasswordToken { /** serialVersionUID */ private static final long serialVersionUID = -4849823851197352099L; private String tokenType; private String quickPassword; /** * Constructor for SimpleToken * @param tokenType */ public SimpleToken(String tokenType, String username,String password) { super(username,password); this.tokenType = tokenType; } public SimpleToken(String tokenType, String username,String password,String quickPassword) { super(username,password); this.tokenType = tokenType; this.quickPassword = quickPassword; } public String getTokenType() { return tokenType; } public void setTokenType(String tokenType) { this.tokenType = tokenType; } public String getQuickPassword() { return quickPassword; } public void setQuickPassword(String quickPassword) { this.quickPassword = quickPassword; }} 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的shiro启动之后页面访问不了_java:shiro入门——4的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java修改已创建程序界面_Java应用
- 下一篇: golang select defaul