分享知识-快乐自己:Shrio 案例Demo概述
Shiro 权限认证核心:
POM:文件:
- <!--shiro-all-->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-all</artifactId>
- <version>1.2.3</version>
- </dependency>
- <!-- 添加shrio-web支持 -->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-web</artifactId>
- <version>1.2.4</version>
- </dependency>
- <!-- 添加shrio-spring支持 -->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-spring</artifactId>
- <version>1.2.4</version>
- </dependency>
- <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-ehcache -->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-ehcache</artifactId>
- <version>1.4.0</version>
- </dependency>
WEB.XML:
- <!--01.配置 Shiro 的 ShiroFilter-->
- <filter>
- <filter-name>shiroFilter</filter-name>
- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
- <init-param>
- <param-name>targetFilterLifecycle</param-name>
- <param-value>true</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>shiroFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
spring-shiro.xml 配置文件:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:p="http://www.springframework.org/schema/p"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:jee="http://www.springframework.org/schema/jee"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
- http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
- <!-- 自定义Realm -->
- <bean id="myRealm"
- class="com.dsj.gdbd.controller.shiro.realm.MyRealm">
- <property name="credentialsMatcher">
- <bean
- class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
- <property name="hashAlgorithmName" value="MD5"></property>
- <property name="hashIterations" value="1"></property>
- </bean>
- </property>
- </bean>
- <bean id="securityManager"
- class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <!-- 注入realm -->
- <property name="realm" ref="myRealm" />
- </bean>
- <!-- 开启Shiro注解 -->
- <bean
- class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
- <property name="securityManager" ref="securityManager" />
- </bean>
- <!-- 重写Shiro登录过滤器 -->
- <bean id="loginAgainFilter"
- class="com.dsj.gdbd.controller.shiro.filter.MyFormAuthenticationFilter"></bean>
- <bean id="shiroFilter"
- class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <!-- Shiro的核心安全接口,这个属性是必须的 -->
- <property name="securityManager" ref="securityManager" />
- <!-- 身份认证失败,则跳转到登录页面的配置(这里的路径与 form 表单路径一致,并且是 POST 请求) -->
- <property name="loginUrl" value="/login/to_login" />
- <!-- 权限认证失败,则跳转到指定页面 -->
- <property name="unauthorizedUrl"
- value="/login/to_unauthorized" />
- <!-- 权限认证成功,则跳转到指定页面 -->
- <property name="successUrl" value="/home/to_index" />
- <property name="filters">
- <map>
- <entry key="mauthc" value-ref="loginAgainFilter" />
- <entry key="logout">
- <!-- 退出之后的重定向地址 -->
- <bean class="org.apache.shiro.web.filter.authc.LogoutFilter">
- <property name="redirectUrl" value="/login/to_login" />
- </bean>
- </entry>
- </map>
- </property>
- <property name="filterChainDefinitions">
- <value>
- <!-- anon 表示可以匿名使用。 -->
- /static/**=anon
- /login/to_login=mauthc
- /login/logout=logout
- /login/**=anon
- <!-- authc表示需要认证(登录)才能使用 -->
- /** = authc
- </value>
- </property>
- </bean>
- </beans>
重写Shiro登录过滤器 :
- package com.dsj.gdbd.controller.shiro.filter;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import org.apache.shiro.authc.AuthenticationToken;
- import org.apache.shiro.subject.Subject;
- import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
- public class MyFormAuthenticationFilter extends FormAuthenticationFilter {
- //重写登录成功
- @Override
- protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
- ServletResponse response) throws Exception {
- //开启授权
- subject.hasRole("*");
- return super.onLoginSuccess(token, subject, request, response);
- }
- }
MyRealm.java 验证授权:
- package com.dsj.gdbd.controller.shiro.realm;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import org.apache.shiro.SecurityUtils;
- 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.authz.AuthorizationInfo;
- import org.apache.shiro.authz.SimpleAuthorizationInfo;
- import org.apache.shiro.realm.AuthorizingRealm;
- import org.apache.shiro.subject.PrincipalCollection;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import com.dsj.gdbd.pojo.MenuFunction;
- import com.dsj.gdbd.pojo.RoleInfo;
- import com.dsj.gdbd.pojo.UserInfo;
- import com.dsj.gdbd.service.MenuFunctionService;
- import com.dsj.gdbd.service.RoleInfoService;
- import com.dsj.gdbd.service.UserInfoService;
- import com.dsj.gdbd.utils.enums.DeleteStatusEnum;
- public class MyRealm extends AuthorizingRealm {
- @Autowired
- private UserInfoService userInfoService;
- @Autowired
- private RoleInfoService roleInfoService;
- @Autowired
- private MenuFunctionService menuFunctionService;
- private final Logger LOGGER = LoggerFactory.getLogger(MyRealm.class);
- @SuppressWarnings("unchecked")
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
- /**
- *
- * 流程 1.根据用户user->2.获取角色id->3.根据角色id获取权限
- */
- // 01、获取用户登陆ing
- String realName = (String) principals.getPrimaryPrincipal();
- LOGGER.info("realName{}", realName);
- // 02、设置查询条件
- UserInfo info = new UserInfo();
- info.setRealName(realName);
- info.setDelFlag(DeleteStatusEnum.NDEL.getValue());
- // 03、查询对象信息
- UserInfo userInfo = userInfoService.getInfo(info);
- LOGGER.info("admin.id{}", userInfo.getId());
- LOGGER.info("admin.name{}", userInfo.getUserName());
- SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
- // 04、获取用户下的所有角色
- List<RoleInfo> rolelist = roleInfoService.getRoles(userInfo.getId());
- // 获取所有角色的 Id
- List<Long> rolesIds = new ArrayList<Long>();
- for (RoleInfo item : rolelist) {
- rolesIds.add(item.getId());
- }
- // 05、角色下所拥有的所有权限
- List<MenuFunction> listMenus = menuFunctionService.getListMenus(rolesIds);
- // 获取访问的权限
- List<String> patterns = new ArrayList<String>();
- for (MenuFunction item : listMenus) {
- patterns.add(item.getPattern());
- }
- // 06、设置绑定 分类级别关系
- List<MenuFunction> menuFunction = menuFunction(listMenus);
- // 07、去掉空的权限
- List<MenuFunction> notNullMenus = notNull(menuFunction);
- // 08、权限菜单集合保存在Session 回话中
- SecurityUtils.getSubject().getSession().setAttribute("menus", notNullMenus);
- // 09、当前用户所拥有的所有权限保存在 session 会话中进行对比
- SecurityUtils.getSubject().getSession().setAttribute("menusPatterns", patterns);
- // 10、当前登录的用户信息
- SecurityUtils.getSubject().getSession().setAttribute("sessionUser", userInfo);
- // 11、将用户拥有的权限保存在 shiro中 用于后期页面的权限验证
- authorizationInfo.addStringPermissions(
- (List<String>) SecurityUtils.getSubject().getSession().getAttribute("menusPatterns"));
- return authorizationInfo;
- }
- /***
- * 认证方法 验证账号密码
- */
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {
- System.out.println("进行验证了");
- // 01、获取登录用户名
- String realName = (String) authenticationToken.getPrincipal();
- // 02、设置条件
- UserInfo info = new UserInfo();
- info.setRealName(realName);
- info.setDelFlag(DeleteStatusEnum.NDEL.getValue());
- // 03、查询对象信息
- UserInfo userInfo = userInfoService.getInfo(info);
- if (userInfo == null) {
- throw new UnknownAccountException();
- }
- // 最后的比对需要交给安全管理器
- // 三个参数进行初步的简单认证信息对象的包装(验证密码)
- SimpleAuthenticationInfo authcInfo = new SimpleAuthenticationInfo(userInfo.getRealName(), userInfo.getUserPwd(),
- this.getName());
- return authcInfo;
- }
- /***
- * 执行遍历
- *
- * @param menus
- * 所有权限列表集合
- * @param list
- * 指定角色查询到的 权限Id
- * @return
- */
- @SuppressWarnings("unused")
- private List<MenuFunction> menuFunction(List<MenuFunction> menus) {
- // 中转集合
- List<MenuFunction> functions = null;
- try {
- functions = new ArrayList<MenuFunction>();
- // 循环遍历菜单层级关系
- // 循环遍历
- for (MenuFunction item : menus) {
- // 获取pid
- long pid = item.getPid();
- if (pid == 0) {
- // 遍历一级分类
- functions.add(item);
- } else {
- for (MenuFunction innerCate : menus) {
- /***
- * 外层循环 pid 没有的等于0 的话 获取当前对象的 id 作为一级
- */
- Long id = innerCate.getId();
- if (id == pid) {
- innerCate.getChildren().add(item);
- break;
- }
- }
- }
- }
- } catch (Exception e) {
- LOGGER.error("循环遍历层级关系失败!!!" + e);
- }
- return functions;
- }
- /***
- * 去掉空的权限
- *
- * @param list
- * @return
- */
- private List<MenuFunction> notNull(List<MenuFunction> list) {
- List<MenuFunction> menusList = null;
- try {
- // 去掉空的权限
- menusList = new ArrayList<MenuFunction>();
- for (int i = 0; i < list.size(); i++) {
- if (list.get(i).getChildren().size() != 0) {
- menusList.add(list.get(i));
- notNull(list.get(i).getChildren());
- }
- }
- } catch (Exception e) {
- LOGGER.error("去除空的权限时意外出错!!!" + e);
- }
- return menusList;
- }
- }
Controller 关键代码:
- package com.dsj.gdbd.controller.login;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- /***
- * 登陆
- * @author asus
- *
- */
- @Controller
- @RequestMapping("login")
- public class LoginController {
- /***
- * 跳转登录页
- * @return
- */
- @RequestMapping("to_login")
- public String login() {
- return "login/login";
- }
- }
- package com.dsj.gdbd.controller.home;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- @Controller
- @RequestMapping("home")
- public class HomeController {
- /***
- * 跳转主页面
- * @return
- */
- @RequestMapping("to_index")
- public String login() {
- return "home/welcome";
- }
- }
login.jsp:登录页:(重点关注 form 表单 与 异常处理 )
- <%@ page contentType="text/html;charset=UTF-8"%>
- <%@include file="/WEB-INF/jsp/common/taglibs.jspf"%>
- <html lang="en">
- <head>
- <link rel="stylesheet" href="${ctx}/static/front/css/login/style.css">
- <link rel="stylesheet"
- href="${ctx}/static/front/bootstrap/3.3.7/css/bootstrap.min.css">
- <script src="${ctx}/static/front/js/jquery.min.js"></script>
- <script src="${ctx}/static/front/bootstrap/3.3.7/js/bootstrap.min.js"></script>
- <script src='${ctx}/static/front/js/style.js'></script>
- <script type="text/javascript">
- var _ctx = '${ctx}';
- </script>
- <title>登录</title>
- </head>
- <style>
- </style>
- <body>
- <!-- <div class="bj"> -->
- <header>
- <img src="${ctx}/static/front/images/login/logo.png" alt="">
- </header>
- <!-- </div> -->
- <div class="city">
- <img src="${ctx}/static/front/images/login/4.png" alt="">
- <div class="denglu">
- <div class="titBian">
- <span class="tit">用户登录</span>
- </div>
- <form id="loginForm" action="${ctx }/login/to_login" method="post">
- <div class="fengexian"></div>
- <div class=" alert-danger dengLuTiShi" id="errorDiv">
- <span class="dengLuTiShiTu glyphicon glyphicon-minus-sign"></span><span
- id="error" class="cuo">${errormsg }</span>
- </div>
- <div class="input-group name">
- <span class="input-group-addon tx1" id="basic-addon1"><img
- id="tx" class="tupian"
- src="${ctx}/static/front/images/login/tuyiyi-com-0.png" alt=""></span>
- <input type="text" id="phone" onclick="phone2()" name="username"
- class="form-control" autocomplete="off" placeholder="请输入手机号或账号"
- aria-describedby="basic-addon1"> <span
- class="input-group-addon cha1" id="cha" onclick="qingkong()">X</span>
- </div>
- <div class="input-group password">
- <span class="input-group-addon tx1" id="basic-addon2"><img
- src="${ctx}/static/front/images/login/7.png" id="mm"
- class="tupian" alt=""></span> <input type="password" id="mima"
- name="password" class="form-control" onclick="mma()"
- autocomplete="off" placeholder="请输入密码"
- aria-describedby="basic-addon1">
- </div>
- <span class="wangjimima" onclick="wangji()">忘记密码</span>
- <button id="login_btn" type="button" class="btn btn-primary btnDL">登录</button>
- </form>
- <%
- //shiro 获取异常,判断异常类型
- Object errorClass = request.getAttribute("shiroLoginFailure");
- if ("org.apache.shiro.authc.IncorrectCredentialsException".equals(errorClass)) {
- request.setAttribute("errormsg", "用户名或密码错误");
- }
- if ("org.apache.shiro.authc.UnknownAccountException".equals(errorClass)) {
- request.setAttribute("errormsg", "用户不存在或已禁用");
- }
- if ("com.dsj.data.shiro.filter.VerifyCodeException".equals(errorClass)) {
- request.setAttribute("errormsg", "验证码不正确");
- }
- %>
- </div>
- </div>
- <div class="yun">
- <div class="kuanCont">
- <a class="kuan"> 联系我们xxxxx </a> <a
- class="kuan kuanLast"> 北京xxxxx技术服务有限公司 </a>
- </div>
- </div>
- <script type="text/javascript">
- $(function() {
- $("#login_btn").off().on("click", function() {
- $("#loginForm").submit();
- });
- if ('${errormsg }' != '') {
- var errorDiv = document.getElementById('errorDiv');
- $("#error").html("${errormsg }");
- errorDiv.style.visibility = 'visible';
- }
- })
- $(document).keydown(function(event) {
- if (event.keyCode == 13) { //绑定回车
- $('#login_btn').click();
- }
- });
- </script>
- <script src="${ctx }/static/back/login/login.js"></script>
- </body>
- </html>
其他 相关 Shiro 权限 Demo:案例Demo并不是很完整,你只需要拿走里面你需要的配置就好。
分享知识-快乐自己:Shrio 案例Demo概述的更多相关文章
- 分享知识-快乐自己:反射机制Demo解析
Java-Reflect专题 基本反射简介: 1):JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象能够调用它的任意方法和属性;这种动态获取信息以及动 ...
- 分享知识-快乐自己:Mybatis 基础动态语句
目录: User: package mlq.bean; /** * 用户实体类 */ public class User { private Integer uId; private String u ...
- 分享知识-快乐自己:Struts2(动态方法、动态结果、通配符、方法内部跳转、action跳转、OGNL 的使用及注意事项)
这里主要以案例演示:涵盖以下知识点 1.动态方法调用:使用关键 符号 ! 进行操作 例如:/命名空间 ! 方法名 2.动态结果集:就是说,通过后台返回的结果 ${} 获取,重定向到符合预期的页面. ...
- 分享知识-快乐自己:全面解析 java注解实战指南
请你在看这篇文章时,不要感到枯燥,从头到尾一行行看,代码一行行读,你一定会有所收获的. 问: 为什么学习注解? 学习注解有什么好处? 学完能做什么? 答: 1):能够读懂别人的代码,特别是框架相关的代 ...
- 分享知识-快乐自己:运行(wordcount)案例
运行 wordcount 案例: 一):大数据(hadoop)初始化环境搭建 二):大数据(hadoop)环境搭建 三):运行wordcount案例 四):揭秘HDFS 五):揭秘MapReduce ...
- 分享知识-快乐自己:Nginx概述及如何使用
概述: 什么是 Nginx? Nginx (engine x) 是一款轻量级的 Web 服务器 .反向代理服务器及电子邮件(IMAP/POP3)代理服务器. 什么是反向代理? 反向代理(Reverse ...
- 分享知识-快乐自己:SSH 整合 Demo
楼主A: XML 版 SSH整合Demo https://github.com/MlqBeginner/BlogGardenWarehouse/blob/master/SSH%E6%95%B4%E5% ...
- 分享知识-快乐自己:初始 Struts2 (基本概念)及 搭建第一个Demo
1):struts2 的基本概念: 1-1):Struts2 是什么? 1.Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2 ...
- 分享知识-快乐自己:搭建第一个 Hibernate (Demo)
使用 Hibernate 完成持久化操作 七大 步骤: 1.读取并解析配置文件及映射文件: Configuration configuration=new Configuration().config ...
随机推荐
- NHibernate 组件基础 (第六篇)
NHibernate 组件基础 (第六篇) 一.组件简介 组件(Component)可以理解为被一个对象所包含的对象而持久化,而并非一个实体.简单说来,假如数据库有FirstName,LastName ...
- Java并发编程(一)学习大纲
(一)学习大纲 (二)线程与并发编程的概念 (三)线程安全.原子操作.复合操作.竞态条件.加锁机制(内置锁.重入) (四)对象的共享:可见性.失效数据.非原子的64位操作,加锁与可见性,volatil ...
- maven 依赖文件 pom.xml 编译 mvn compile 运行 不用mvn exec:java -Dexec.mainClass="hello.HelloWorld" 打成jar包 mvn package mvn install http://blog.csdn.net/yaya1943/article/details/48464371
使用maven编译Java项目 http://blog.csdn.net/yaya1943/article/details/48464371 使用"mvn clean"命令清除编 ...
- easyui combobox 三级级联 input 两种实现
/**<img src='${pageContext.request.contextPath}/images/block.png'/> * @param 默认载入 省市 */ $(func ...
- SourceTree超前一个版本,落后N个版本
SourceTree超前一个版本,落后N个版本 在使用SourceTree的时候经常会遇见超前一个版本,落后N个版本的情况,遇见这种情况应该怎么办呢? 首先打开终端,最好是从SourceTree里 ...
- iOS开发 Xcode8 问题
一.证书管理 用Xcode8打开工程后,比较明显的就是下图了,这个是苹果的新特性,可以帮助我们自动管理证书.建议大家勾选这个Automatically manage signing(Ps.但是在b ...
- ios推送服务,php服务端
本文转载至http://my.oschina.net/AStar/blog/176531 生成证书 证书生成参考:https://parse.com/tutorials/ios-push-noti ...
- Idiomatic Phrases Game(图论最短路)
Idiomatic Phrases Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/O ...
- ubuntu下操作端口的方法
最简单的一个操作:sudo ufw status可检查防火墙的状态,我的返回的是:不活动 sudo ufw version防火墙版本: ufw 0.29-4ubuntu1 Copyright 2008 ...
- 算法调参 weight_ratio, weight_seqratio
from openpyxl import Workbook import xlrd import time import Levenshtein as Le target_city_list = [' ...