Shiro安全框架入门使用方法

详见: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,当捕获异常,表示用户身份验证失败。

原文地址:https://www.cnblogs.com/lukelook/p/11247760.html

时间: 2024-08-25 15:11:22

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

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

一.Shiro框架简单介绍 Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权.Shiro在JavaSE和JavaEE项目中都可以使用.它主要用来处理身份认证,授权,企业会话管理和加密等.Shiro的具体功能点如下: (1)身份认证/登录,验证用户是不是拥有相应的身份: (2)授权,即权限验证,验证某个已认证的用户是否拥有某个权限:即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色.或者细粒度的验证某个用户对某个资源是否具有某个权限: (3)会话管理,即用户登录

Shiro安全框架入门

完整学习网址:https://www.w3cschool.cn/shiro 一.Shiro简介 1.Shiro的概念 Apache Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能. 认证(Authentication):用户身份识别,常被称为用户"登录",判断用户是否登陆,如果未登陆,则拦截其请求.优点:可以实现单点登录,多个子系统登录一个其他子系统也自动登录.(如登录了淘宝,天猫也自动登录了) 授权(Authorization):访问控制.当用户登

Shiro安全框架入门篇

一.Shiro框架介绍 Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权.Shiro在JavaSE和JavaEE项目中都可以使用.它主要用来处理身份认证,授权,企业会话管理和加密等.Shiro的具体功能点如下: (1)身份认证/登录,验证用户是不是拥有相应的身份: (2)授权,即权限验证,验证某个已认证的用户是否拥有某个权限:即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色.或者细粒度的验证某个用户对某个资源是否具有某个权限: (3)会话管理,即用户登录后就

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

Shiro 简介 照例又去官网扒了扒介绍: Apache Shiro? is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro's easy-to-understand API, you can quickly and easily secure any ap

Shiro权限控制框架入门1:Shiro的认证流程以及基本概念介绍

前言:我在最开始学习Shiro这个框架时,在网上搜索到的一个介绍比较全面的教程是:<跟我学Shiro>系列教程.但是在我看了他写的前几篇文章后,我发现虽然他在这个系列教程中把shiro的一些特性介绍地非常全面详细,但是整个教程的叙述方式还是有很大缺陷的.文章与文章之间并没有很好地串联起来,每篇文章介绍的东西都过于分散了,如果是对shiro完全不了解的新手来看的话完全是一场噩梦.就像一个网友评价的这样: 看了看这个教程,看完之后都想放弃shiro了,完全看不懂,后来百度了很多别的资料才理解了sh

BOS项目 第7天(shiro权限框架进行认证和授权)

BOS项目笔记 第7天 今天内容安排: 1.权限概述(认证.授权) 2.常见的权限控制的方式(URL拦截权限控制.方法注解权限控制) 3.权限数据模型(权限表.角色表.用户表.角色权限关系表.用户角色关系表) 4.shiro框架入门 5.将shiro应用到bos项目中进行认证和授权 1. 权限概述 系统提供了很多功能,并不是所有的用户登录系统都可以操作这些功能.我们需要对用户的访问进行控制. 认证:系统提供的用于识别用户身份的功能(通常是登录功能)-----让系统知道你是谁?? 授权:系统提供的

shiro安全框架

原文:http://blog.csdn.net/boonya/article/details/8233303 可能大家早先会见过 J-security,这个是 Shiro 的前身.在 2009 年 3 月初之前,这个安全框架叫做 J-security,由于某些原因,更名为 Shiro(或者 Ki,意为 Fortress),是 Apache 的孵化项目,鉴于本文编写时 Shiro 的还没有正式发布的版本,本文使用的是 Jsecurity 的稳定版本 0.9,本文中 Shiro 等同于 Jsecur

Farseer.net轻量级开源框架 入门篇:使用前说明

导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 框架性能测试 下一篇:Farseer.net轻量级开源框架 入门篇: 增.删.改.查操作演示 本篇讲解使用或者学习Farseer前需要知道一些事项: 在后续很多演示中,使用了很多扩展方法.但作者并没有明确出哪些是扩展的方法.所以读者要注意.在使用框架的时候,都需要引用扩展方法的命名空间:using FS.Extend; 为了方便,扩展方法统一放到FS.Extend中,在这里特别说

(转) shiro权限框架详解06-shiro与web项目整合(上)

http://blog.csdn.net/facekbook/article/details/54947730 shiro和web项目整合,实现类似真实项目的应用 本文中使用的项目架构是springMVC+mybatis,所以我们是基于搭建好的项目进行改造的. 将shiro整合到web应用中 登录 退出 认证信息在页面展现,也就是显示菜单 shiro的过滤器 将shiro整合到web应用中 数据库脚步 sql脚步放到项目中,项目上传到共享的资源中,文章最后给出共享url. 去除项目中不使用shi