shiro框架的认识与使用

本文详细介绍Apache Shiro权限框架的基础知识,包括其与Spring Security的区别、四大基石、核心API的使用方法及密码加密功能。此外,还介绍了如何通过自定义Realm实现登录认证和授权,并演示了Shiro与Spring集成的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.shiro的认识

权限框架(提供的易用的API,功能强大)

1.1 和Spring security区别

框架shiroSpring security
易用性X
粒度细(强大)

1.2 shiro的四大基石

身份验证、授权、密码学和会话管理
securityManager:核心对象 realm:获取数据接口

2.shiro的核心api

2.1 操作之前,先得到securityManager对象

//一.创建我们自己的Realm
MyRealm myRealm = new MyRealm();

//二.搞一个核心对象:
DefaultSecurityManager securityManager = new DefaultSecurityManager();
securityManager.setRealm(myRealm);

//三.把securityManager放到上下文中
SecurityUtils.setSecurityManager(securityManager);

2.2 我们使用过的方法

//1.拿到当前用户
Subject currentUser = SecurityUtils.getSubject();
//2.判断是否登录
currentUser.isAuthenticated();
//3.登录(需要令牌的)
/**
UnknownAccountException:用户名不存在
IncorrectCredentialsException:密码错误
AuthenticationException:其它错误
*/
UsernamePasswordToken token = new UsernamePasswordToken(“admin”, “123456”);
currentUser.login(token);

//4.判断是否是这个角色/权限
currentUser.hasRole(“角色名”)
currentUser.isPermitted(“权限名”)

3.密码加密功能

/**

  • String algorithmName, Object source, Object salt, int hashIterations)
  • 第一个参数algorithmName:加密算法名称
  • 第二个参数source:加密原密码
  • 第三个参数salt:盐值
  • 第四个参数hashIterations:加密次数
    */
    SimpleHash hash = new SimpleHash(“MD5”,“123456”,“itsource”,10);
    System.out.println(hash.toHex());

4.自定义Realm

继承AuthorizingRealm

实现两个方法:doGetAuthorizationInfo(授权) /doGetAuthenticationInfo(登录认证)

//身份认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//1.拿用户名与密码
UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
String username = token.getUsername();
//2.根据用户名拿对应的密码
String password = getByName(username);
if(password==null){
return null; //返回空代表用户名有问题
}
//返回认证信息
//准备盐值
ByteSource salt = ByteSource.Util.bytes(“itsource”);
//密码是shiro自己进行判断
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username,password,salt,getName());
return authenticationInfo;
}

//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//拿到用户名 Principal:主体(用户对象/用户名)
String username = (String)principalCollection.getPrimaryPrincipal();
//拿到角色
Set roles = findRolesBy(username);
//拿到权限
Set permis = findPermsBy(username);
//把角色权限交给用户
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(roles);
authorizationInfo.setStringPermissions(permis);
return authorizationInfo;
}

注意:如果我们的密码加密,应该怎么判断(匹配器)

//一.创建我们自己的Realm
MyRealm myRealm = new MyRealm();
//创建一个凭证匹配器(无法设置盐值)
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
// 使用MD5的方式比较密码
matcher.setHashAlgorithmName(“md5”);
// 设置编码的迭代次数
matcher.setHashIterations(10);
//设置凭证匹配器(加密方式匹配)
myRealm.setCredentialsMatcher(matcher);

5.集成Spring

去找:shiro-root-1.4.0-RC2\samples\spring

5.1 导包

org.apache.shiro shiro-all 1.4.0 pom org.apache.shiro shiro-spring 1.4.0

5.2 web.xml

这个过滤器是一个代码(只关注它的名称)

shiroFilter org.springframework.web.filter.DelegatingFilterProxy targetFilterLifecycle true shiroFilter /*

5.3 application-shiro.xml

在咱们的application引入

<import resource="classpath:applicationContext-shiro.xml" />

是从案例中拷备过来,进行了相应的修改

<?xml version="1.0" encoding="UTF-8"?>

<!-- 创建securityManager这个核心对象 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <!-- 设置一个realm进去 -->
    <property name="realm" ref="jpaRealm"/>
</bean>

<!-- 被引用的realm(一定会写一个自定义realm) -->
<bean id="jpaRealm" class="cn.itsource.aisell.shiro.JpaRealm">
    <!-- 为这个realm设置相应的匹配器 -->
    <property name="credentialsMatcher">
        <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
            <!-- 设置加密方式 -->
            <property name="hashAlgorithmName" value="md5"/>
            <!-- 设置加密次数 -->
            <property name="hashIterations" value="10" />
        </bean>
    </property>
</bean>

<!--  可以让咱们的权限判断支持【注解】方法 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
      depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager"/>
</bean>


<!--  真正实现权限的过滤器 它的id名称和web.xml中的过滤器名称一样 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager"/>
    <!-- 登录路径:如果没有登录,就会跳到这里来 -->
    <property name="loginUrl" value="/s/login.jsp"/>
    <!-- 登录成功后的跳转路径 -->
    <property name="successUrl" value="/s/main.jsp"/>
    <!-- 没有权限跳转的路径 -->
    <property name="unauthorizedUrl" value="/s/unauthorized.jsp"/>
    <!--
        anon:这个路径不需要登录也可以访问
        authc:需要登录才可以访问
        perms[depts:index]:做权限拦截
            咱们以后哪些访问有权限拦截,需要从数据库中读取
    -->
    <!--
    <property name="filterChainDefinitions">
        <value>
            /s/login.jsp = anon
            /login = anon
            /s/permission.jsp = perms[user:index]
            /depts/index = perms[depts:index]
            /** = authc
        </value>
    </property>
    -->
    <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap" />
</bean>
<!-- 实例工厂设置 -->
<bean id="filterChainDefinitionMap"
      factory-bean="filterChainDefinitionMapFactory"
      factory-method="createFilterChainDefinitionMap" />
<!-- 创建可以拿到权限map的bean -->
<bean id="filterChainDefinitionMapFactory" class="cn.itsource.aisell.shiro.FilterChainDefinitionMapFactory" />

5.4 获取Map过滤

注意,返回的Map必需是有序的(LinkedHashMap)

public class FilterChainDefinitionMapFactory {

/**
 * 后面这个值会从数据库中来拿
 * /s/login.jsp = anon
 * /login = anon
 * /s/permission.jsp = perms[user:index]
 * /depts/index = perms[depts:index]
 * /** = authc
 */
public Map<String,String> createFilterChainDefinitionMap(){
    //注:LinkedHashMap是有序的
    Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();

    filterChainDefinitionMap.put("/s/login.jsp", "anon");
    filterChainDefinitionMap.put("/login", "anon");
    filterChainDefinitionMap.put("/s/permission.jsp", "perms[user:index]");
    filterChainDefinitionMap.put("/depts/index", "perms[depts:index]");
    filterChainDefinitionMap.put("/**", "authc");

    return filterChainDefinitionMap;
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值