详见:https://blog.csdn.net/qq_32651225/article/details/77199464

框架介绍
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任
何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。

Shrio的主要功能:

Authentication:用户认证(登录)
Authorization:权限控制
Session Management:会话管理
Cryptography:数据加密
Web Support:支持web的API
Caching:缓存
Concurrency:支持多线程应用程序
Testing:测试的支持
“Run As”:假设一个用户为另一个用户的身份
“Remember Me”:在Session中保存用户身份
基本原理
Shiro的基本架构:

Shiro有三个核心的概念:Subject、SecurityManager和Realms。

Subject:Subject实质上是一个当前执行用户的特定的安全“视图”,开发者所写的应用代码就通过Subject与Shiro框架进行交互。所有Subject实例都必须绑定到一个SecurityManager上,当使用一个Subject实例时,Subject实例会和SecurityManager进行交互,完成相应操作。

SecurityManager:SecurityManager是Shiro的核心部分,作为一种“保护伞”对象来协调内部安全组件共同构成一个对象图。开发人员并不直接操作SecurityManager,而是通过Subject来操作SecurityManager来完成各种安全相关操作。

Realms:Realms担当Shiro和应用程序的安全数据之间的“桥梁”或“连接器”。从本质来讲,Realm是一个特定安全的DAO,Realm中封装了数据操作的模块和用户自定义的认证匹配过程。SecurityManager可能配置多个Realms,但至少要有一个。

使用方法

注:该示例基于一个Maven管理的SSH项目

1.在Maven中添加Shiro依赖

<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.2.3</version>
</dependency>

注:Shiro官方现在不推荐这种用法,因为可能会导致Maven运行错误,详见:http://shiro.apache.org/download.html#latest

2.在web.xml添加核心过滤器,且必须放在Struts2核心过滤器前面

<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>

3.在Spring配置文件中添加如下代码,且放在事务管理器之前

<!--Shiro安全框架产生代理子类的方式: 使用cglib方式,放在事务管理器之前-->
<aop:aspectj-autoproxy proxy-target-class="true" />

4.在Spring配置文件中配置Shiro,建议单独出一个applicationContext-shiro.xml进行配置(编写完成后记得在总的配置文件中引入该配置文件)

applicationContext-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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!-- SecurityManager配置 -->
<!-- 配置Realm域 -->
<!-- 密码比较器 -->
<!-- 配置缓存:ehcache缓存 --> <!-- 安全管理 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 引用自定义的realm -->
<property name="realm" ref="authRealm"/>
<!-- 缓存 -->
<property name="cacheManager" ref="shiroEhcacheManager"/>
</bean> <!-- 自定义权限认证 -->
<bean id="authRealm" class="com.songzheng.demo.shiro.AuthRealm">
<property name="userService" ref="userService"/>
<!-- 自定义密码加密算法 -->
<property name="credentialsMatcher" ref="passwordMatcher"/>
</bean> <!-- 设置密码加密策略 md5hash -->
<bean id="passwordMatcher" class="com.songzheng.demo.shiro.DemoCredentialsMatcher"/> <!-- filter-name这个名字的值来自于web.xml中filter的名字 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<!--登录页面 -->
<property name="loginUrl" value="/index.jsp"></property>
<!-- 登录成功后 -->
<property name="successUrl" value="/home.action"></property>
<property name="filterChainDefinitions">
<!-- /**代表下面的多级目录也过滤 -->
<value>
/index.jsp* = anon
/home* = anon
/sysadmin/login/login.jsp* = anon
/sysadmin/login/logout.jsp* = anon
/login* = anon
/logout* = anon
/components/** = anon
/css/** = anon
/images/** = anon
/js/** = anon
/make/** = anon
/skin/** = anon
/stat/** = anon
/ufiles/** = anon
/validator/** = anon
/resource/** = anon
/** = authc
/*.* = authc
</value>
</property>
</bean> <!-- 用户授权/认证信息Cache, 采用EhCache 缓存 -->
<bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>
</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> </beans>

在这里配置了核心的SecurityManager,SecurityManager中注入了realm和cacheManager,因此需要配置realm和cacheManager,Realm是自定义的,其中注入了userService,用来进行查询数据库数据的相关操作,还注入了credentialsMatcher属性,这个是开发者自定义的比较器。配置CacheManager时,使用了ehcache,在最后也进行了配置,并且编写了ehcache的配置文件,这些操作在下述步骤进行。

在shiroFilter的配置中配置了要过滤的目录,其中一个*号表示匹配当前目录后的参数,两个*号表示匹配该目录及其子目录及参数。等号后面是Shiro各类过滤器的简称,anon表示匿名过滤器,表示可以匿名访问这些资源,authc表示需要验证用户身份才能访问,还有8种过滤器,在此就不再详述了。

5.Ehcache的配置文件

ehcache-shiro.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" name="shiroCache"> <defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"/> </ehcache>

6.编写自定义的credentialsMatcher

DemoCredentialsMatcher.java

public class DemoCredentialsMatcher extends SimpleCredentialsMatcher {

    /**
* 密码比较的规则
* token:用户在界面输入的用户名和密码
* info: 从数据库中得到的加密数据
*/
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
// 获取用户输入的密码,并加密
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String md5Pwd = Encrypt.md5(new String(upToken.getPassword()), upToken.getUsername()); // 获取数据库中的加密密码
String pwd = (String) info.getCredentials(); // 返回比较结果
return this.equals(md5Pwd, pwd);
} }

Encrypt是一个进行MD5加密的工具类

Encrypt.java

public class Encrypt {
public static String md5(String password, String salt) {
return new Md5Hash(password, salt, 2).toString();
}
}

7.编写自定义的realm

AuthRealm.java

public class AuthRealm extends AuthorizingRealm {

    private IUserService userService;

    public void setUserService(IUserService userService) {
this.userService = userService;
} /**
* 授权,当jsp页面遇到shiro标签会执行该方法
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
System.out.println("授权");
User user = (User) pc.fromRealm(this.getName()).iterator().next(); // 根据realm名字找到对应的realm List<String> permissions = new ArrayList<String>(); Set<Role> roles = user.getRoles();
for (Role role : roles) {
Set<Module> modules = role.getModules();
for (Module module : modules) {
permissions.add(module.getName());
}
} SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(permissions); // 添加用户的权限 return info;
} /**
* 认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("认证");
UsernamePasswordToken upToken = (UsernamePasswordToken) token; List<User> list = userService.find("from User u where u.userName = ?", User.class, new String[]{upToken.getUsername()}); if (list != null && list.size() > 0) {
User user = list.get(0);
AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
return info;
} return null; // 返回null抛出异常
} }

8.登录操作

try {
// 1、得到Subject
Subject subject = SecurityUtils.getSubject(); // 2、调用登录方法---AuthRealm#doGetAuthenticationInfo()
subject.login(new UsernamePasswordToken(username, password)); // 3、登录成功
User user = (User) subject.getPrincipal(); // 4、放入session
session.put(SysConstant.CURRENT_USER_INFO, user);
} catch (Exception e) {
e.printStackTrace();
request.put("errorInfo", "用户名或密码错误!");
return "login";
} return SUCCESS;

在Shiro框架中,如果登陆失败,则会抛出异常,所有在使用Subject的代码外要使用try-catch,当捕获异常,表示用户身份验证失败。

Shiro安全框架入门使用方法的更多相关文章

  1. Shiro安全框架入门篇(登录验证实例详解与源码)

    转载自http://blog.csdn.net/u013142781 一.Shiro框架简单介绍 Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权.Shiro在JavaSE和J ...

  2. Shiro安全框架入门篇

    一.Shiro框架介绍 Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权.Shiro在JavaSE和JavaEE项目中都可以使用.它主要用来处理身份认证,授权,企业会话管理和加 ...

  3. Shiro安全框架入门笔记

    入门 1.simpleRealmTest package cn.realm; import org.apache.shiro.SecurityUtils; import org.apache.shir ...

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

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

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

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

  6. Shiro官方快速入门10min例子源码解析框架2-Session

    Shiro自身维护了一套session管理组件,它可以独立使用,并不单纯依赖WEB/Servlet/EJB容器等环境,使得它的session可以任何应用中使用. 2-Session)主要介绍在quic ...

  7. Shiro官方快速入门10min例子源码解析框架1-初始化

    Shiro,一个易用的Java安全框架,主要集合身份认证.授权.加密和session管理的功能. 这系文章主要简介Shiro架构,并通过官方的quickstart例程分析最简实现下Shiro的工作流程 ...

  8. Shiro安全框架的说明及配置入门

    Shiro是什么? Shiro是一个非常强大的,易于使用的,开源的,权限框架.它包括了权限校验,权限授予,会话管理,安全加密等组件 什么时候使用它呢? 如果你是设计RBAC基础系统,需要编写大量用于权 ...

  9. 30、shiro框架入门2,关于Realm

    1.Jdbc的Realm链接,并且获取权限 首先创建shiro-jdbc.ini的配置文件,主要配置链接数据库的信息 配置文件中的内容如下所示 1.变量名=全限定类名会自动创建一个类实例 2.变量名. ...

随机推荐

  1. [整理]Python程序员面试前需要看的博客(持续整理)

    基本素养 如何聪明的提问 面试方法 从面试官角度来告诉大家,哪些人能面试成功 如何在面试中介绍自己的项目经验 计算机系统 [面试] 迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清 ...

  2. Game and Application Protocol

    This privacy policy details the information collected by the team ("we" or "our" ...

  3. Spring Boot与MyBatis的集成

    SSM(Spring+Spring MVC+MyBatis)是当前主流的框架组合开发方式之一,普遍被应用于互联网项目中.如果要使用Spring Boot开发一个基于SSM框架的应用,那么我们要怎么做呢 ...

  4. 迅速生成项目-react-static

    推荐指数:

  5. 基于libuv的TCP设计(三)

      基于libuv的TCP设计(一) 基于libuv的TCP设计(二)   一.第二版本的libuv_tcp已经基本可以使用.不会出错与崩溃现象,支持几百路客户端同时连接.可是有一缺陷就占用CPU非常 ...

  6. 【GStreamer开发】GStreamer基础教程08——pipeline的快捷访问

    目标 GStreamer建立的pipeline不需要完全关闭.有多种方法可以让数据在任何时候送到pipeline中或者从pipeline中取出.本教程会展示: 如何把外部数据送到pipeline中 如 ...

  7. gcc 不同版本的安装

      系统环境centos 6.5 使用root用户进行安装,此方法会将gcc安装至/usr/bin目录下 curl -Lks http://www.hop5.in/yum/el6/hop5.repo ...

  8. mysql 5.7 停电导致无法启动、如何备份数据,重新安装mysql

    用于记录服务器停电导致,mysql启动失败后,如何备份数据,重新安装mysql,主要分为数据备份,mysql重新安装. 1.mysql无法启动时,进行数据备份. 执行:systemctl start ...

  9. [转帖]Epoll和IOCP的比较

    Epoll和IOCP的比较 https://yq.aliyun.com/articles/53621/   kryptosx 2016-05-27 23:32:51 浏览6181   原来整理过一个& ...

  10. [转帖]Red Hat K8s 关键人物 Grant Shipley 跳槽到 VMware

    Red Hat K8s 关键人物 Grant Shipley 跳槽到 VMware   https://news.cnblogs.com/n/641944/ 这四小时的工作效率 太无敌了.. 投递人  ...