基于Shiro的用户认证(不包含授权)

Spring整合Shiro

shiro原理

1.1   搭建环境

1.1.1      web模块 pom.xml

<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!--shiro核心包-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>

1.1.2  Web.xml配置

<!-- Shiro Security filter  filter-name这个名字的值将来还会在spring中用到,本段代码原样粘贴,注意该过滤器是代理过滤器,它什么都不干,可以通过再Spring整合中配置相应的过滤器权限拦截器进行相应的过滤器拦截-->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<!--如果设置"targetFilterLifecycle"为true,则spring来管理Filter.init()和Filter.destroy();若为false,则这两个方法失效-->
<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>

1.1.3  Spring整合shiro  applicationContext-shiro.xml

 <description>Shiro与Spring整合</description>

    <!--安全管理器-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 引用自定义的realm -->
<property name="realm" ref="authRealm"/>
</bean> <!-- 自定义Realm域的编写 -->
<bean id="authRealm" class="此处为自定义Realm域的全限定类名">
<!-- 注入自定义Realm域的密码比较器 -->
<property name="credentialsMatcher" ref="customerCredentialsMatcher" ></property>
</bean> <!-- 密码比较器:密码加密和比较 -->
<bean id="customerCredentialsMatcher" class="自定义的证书匹配器所在的全限定类名"/> <!-- filter-name这个名字的值来自于web.xml中filter的名字 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<!--登录页面 -->
<property name="loginUrl" value="/login.jsp"></property>
<!-- 登录失败后 跳转到未经授权的页面 -->
<property name="unauthorizedUrl" value="/unauthorized.jsp"></property>
<!--过滤器链定义,此处为访问路径设置过滤器链-->
<property name="filterChainDefinitions">
<!-- /**代表下面的多级目录也过滤,等号后面的单词就是过滤器 -->
<value> <!--如果该路径的用户不包含“模块管理”权限就禁止访问-->
<!-- /system/module/list.do = perms["模块管理"] userLogin.do /userLogin* = anon
mylogiin.jsp /mylogin* = anon
-->
/index.jsp* = anon
/login.jsp* = anon
/login* = anon
/logout* = anon
/css/** = anon
/img/** = anon
/plugins/** = anon
/make/** = anon
<!--
-->
/** = authc
/*.* = authc
</value>
</property>
</bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- 生成代理,通过代理进行控制 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true"/>
</bean> <!-- 安全管理器 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean> <aop:aspectj-autoproxy proxy-target-class="true"/>

2.1 自定义realm

/**
* 自定义reamlm*/
public class AuthRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Autowired
private ModuleService moduleService;
/**
* 授权管理:授权
*/
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
/**
* 身份认证
* 用于验证输入的用户名密码给,登录
*/
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//1.获取到用户界面输入的用户名和密码
UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
//2.获取用户出入的用户名和密码
String username = upToken.getUsername();
String password = new String(upToken.getPassword());
//3.根据用户名查询用户对象
User user = userService.findByUsername(username);
if(user != null) {
//第一个参数:安全数据(user对象)
//第二个参数:密码(数据库密码)
//第三个参数:当前调用realm域的名称(类名即可)
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
return info;
}
return null; //subject.login()方法的时候会抛出异常
}
}
AuthorizingRealm抽象类中被重写的方法来源

2.2 自定义密码比较

在spring与shiro的整合文件中已经将该类交给realm域中,所以直接重写方法doCredentialsMatch即可

/**
* 密码比较器
*/
public class CustomCredentialsMatcher extends SimpleCredentialsMatcher { /**
* 用户密码比较
* 1.对用户输入的密码进行加密
* 2.比较用户输入的密码和数据库密码是否一致
* @param token 用户界面输入的邮箱和密码
* @param info 安全数据:用户对象user
*
* 111111 + 固定值(加盐) = xxxxxx
*/
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
//1.获取用户输入的密码
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String loginPassword = new String(upToken.getPassword());
String email = upToken.getUsername();
//2.对登录密码进行加密
//加密:使用MD5加密
String md5Paasword = Encrypt.md5(loginPassword, email);//密码,盐 //info.getPrincipals();//获取安全数据,用户对象
//获取数据库密码
String dbPassword = (String)info.getCredentials(); //true:登录成功,false:抛出异常
return md5Paasword.equals(dbPassword);
}
}

2.3 用户登录url映射

//用户登录
@RequestMapping("/login")
public String login(String username,String password) { //1、通过shiro框架提供的SecurityUtils工具类获取Subject
Subject subject = SecurityUtils.getSubject();
//2、构造用户名密码的安全对象upToken
UsernamePasswordToken upToken = new UsernamePasswordToken(username,password);
//3、通过Subject的login()方法将安全对象交给shiro的安全管理器SecurityManager
subject.login(upToken);
//4、通过shiro获取用户对象主体,保存到session
User user = (User) subject.getPrincipal(); //获取完全对象
session.setAttribute("user",user);
//5、查询菜单数据
List<Module> moduleList = moduleService.findModuleByUserid(user.getId());
session.setAttribute("modules",moduleList);
return "home/main";
}

 shiro学习推荐阅读》》》》》

》》》shiro的权限管理的注解开发只需要一个注解代码

 /**
* RequiresPermissions:
* value : 权限名称(标识)
* 如果具备此权限:进入方法
* 不具备此权限:抛出异常
*/
@RequiresPermissions("模块管理")
@RequestMapping(value = "/list",name = "查询所有")
public String list(@RequestParam(defaultValue = "1")int page,@RequestParam(defaultValue = "3")int size){
PageInfo info = moduleService.findAll(page,size);
request.setAttribute("page",info);
return "system/module/module-list";
}

2.4   页面标签展示

通过shiro标签控制页面按钮和菜单的显示

2.4.1      引入标签库

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

2.4.2      控制显示

<shiro:hasPermission name="删除部门">
<button type="button" class="btn btn-default" title="删除" onclick='deleteById()'><i class="fa fa-trash-o"></i> 删除</button>
</shiro:hasPermission>

2.4 用户退出

//退出
@RequestMapping(value = "/logout",name="用户登出")
public String logout(){
SecurityUtils.getSubject().logout(); //登出
return "forward:login.jsp";
}

shiro自动管理session,此处会将session中的用户信息清除。

shiro获取当前用户的用户名

Subject subject = SecurityUtils.getSubject();
Object principal = subject.getPrincipal();

点击查看SpringBoot整合Shiro

Shiro安全框架案例的更多相关文章

  1. Shiro 安全框架详解二(概念+权限案例实现)

    Shiro 安全框架详解二 总结内容 一.登录认证 二.Shiro 授权 1. 概念 2. 授权流程图 三.基于 ini 的授权认证案例实现 1. 实现原理图 2. 实现代码 2.1 添加 maven ...

  2. Shiro 安全框架详解一(概念+登录案例实现)

    shiro 安全框架详细教程 总结内容 一.RBAC 的概念 二.两种常用的权限管理框架 1. Apache Shiro 2. Spring Security 3. Shiro 和 Spring Se ...

  3. shiro安全框架

    原文:http://blog.csdn.net/boonya/article/details/8233303 可能大家早先会见过 J-security,这个是 Shiro 的前身.在 2009 年 3 ...

  4. Shiro 核心功能案例讲解 基于SpringBoot 有源码

    Shiro 核心功能案例讲解 基于SpringBoot 有源码 从实战中学习Shiro的用法.本章使用SpringBoot快速搭建项目.整合SiteMesh框架布局页面.整合Shiro框架实现用身份认 ...

  5. thymeleaf模板引擎shiro集成框架

    shiro权限框架.前端验证jsp设计.间tag它只能用于jsp系列模板引擎. 使用最近项目thymeleaf作为前端模板引擎,采用HTML档,未出台shiro的tag lib,假设你想利用这段时间s ...

  6. shiro权限框架(一)

    不知不觉接触shiro安全框架都快三个月了,这中间配合项目开发踩过无数的坑.现在回想总结下,也算是一种积累,一种分享.中间有不够完美的地方或者不好的地方,希望大家指出来能一起交流.在这里谢谢开涛老师的 ...

  7. Shiro安全框架【快速入门】就这一篇!

    Shiro 简介 照例又去官网扒了扒介绍: Apache Shiro™ is a powerful and easy-to-use Java security framework that perfo ...

  8. SpringBoot集成Shiro安全框架

    跟着我的步骤:先运行起来再说 Spring集成Shiro的GitHub:https://github.com/yueshutong/shiro-imooc 一:导包 <!-- Shiro安全框架 ...

  9. Shiro权限框架简介

    http://blog.csdn.net/xiaoxian8023/article/details/17892041   Shiro权限框架简介 2014-01-05 23:51 3111人阅读 评论 ...

随机推荐

  1. MSP---企业上云需要考虑的问题

    一.评估 1.应用是否可以上云: 2.时间:规划时间,迁移时间 2.成本:人力成本,资源成本 二.上云 1.如何上云:选择云厂商,选择MSP 2.云选择:公有云,私有云,混合云,多云(不要最贵的,也不 ...

  2. Docker 安装 MySQL 学习笔记

    https://www.runoob.com/docker/docker-install-mysql.html #docker search mysql #docker pull mysql:5.6 ...

  3. Git撤销add、commit

    撤销add git status 查看当下更新的文件 git reset HEAD 表示撤销上次add的所有文件 git reset HEAD dir/dir/test.php 撤销指定文件 撤销co ...

  4. Mysql中use filesort的误区

    误区一字面误区 use filesort排序,字面上理解是外部排序. 误区二人云亦云 百度上多被大家否定不是外部排序,认为和file这个关键字没关系.用的是快速排序.但是总觉得不可能这么无缘无故叫fi ...

  5. 2019-07-25 php错误级别及设置方法

    在php的开发过程里,我们总是会有一系列的错误警告,这些错误警告在我们开发的过程中是十分需要的,因为它能够提示我们在哪里出现了错误,以便修改和维护.但在网站开发结束投入使用时,这些报错我们就要尽量避免 ...

  6. localStorage的增删改查

    var _localStorage = window.localStorage; undefined /* 增 */ _localStorage.name = '张泰松' "张泰松" ...

  7. Web网站实现facebook登录

    一.登录facebook开发者中心:https://developers.facebook.com 二.创建应用编号,如下图: 三.添加产品选择Facebook登录,如下图: 四.facebbok登录 ...

  8. 关闭linux命令行屏幕保护

    # setterm -blank 0

  9. HTTPS安全通信过程

         前言:本文是的第三篇文章.第一篇文章<常见加密算法特点及适用场景>,介绍了常见加密算法及其适用的场景,对加密算法做一个总体的概述.第二篇文章<非对称加密算法-RSA算法&g ...

  10. Docker搭建Portainer

    1.介绍 Docker 图形化管理提供了很多工具,有Portainer.Docker UI.Shipyard等等,本文主要介绍Portainer. Portainer是一个开源.轻量级Docker管理 ...