Shiro(七)配置

209 阅读3分钟

介绍

在使用Shiro框架中我们配置数据的方式通常有以下方式,分别是shiro 提供的ini配置文件、Java代码配置、spring提供xml配置、spring配置类、数据库。通常在SpringBoot项目中对于Shiro的配置采用配置类加读取数据库中的数据(数据库中存储的角色权限信息)。

配置

ini配置文件

在ini配置文件中配置的认证相关、过略相关等配置均需要与手动的与SecurityManager进行关联。 配置原理

  1. 对象名 = 全限定类名 相对于调用 public 无参构造器创建对象
  2. 对象名. 属性名 = 值 相当于调用 setter 方法设置常量值
  3. 对象名. 属性名 =$ 对象引用 相当于调用 setter 方法设置对象引用
[main]
#认证相关配置 认证器、认证策略
authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
authenticationStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
authenticator.authenticationStrategy=$authenticationStrategy
securityManager.authenticator=$authenticator

#授权配置 权限解析器、权限认证
authorizer=org.apache.shiro.authz.ModularRealmAuthorizer
permissionResolver=org.apache.shiro.authz.permission.WildcardPermissionResolver
authorizer.permissionResolver=$permissionResolver
securityManager.authorizer=$authorizer

#数据库和Realm
dataSource=com.alibaba.druid.pool.DruidDataSource
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql://localhost:3306/shiro
dataSource.username=root
dataSource.password=
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource=$dataSource
jdbcRealm.permissionsLookupEnabled=true
securityManager.realms=$jdbcRealm

#配置核心部件 相当于Spring中的DispatcherSelvarlet SecurityManager
securityManager=org.apache.shiro.mgt.DefaultSecurityManager

#提供了对用户/密码及其角色的配置,用户名=密码,角色1,角色2
[users]
username=password,role1,role2

#角色及权限之间关系的配置,角色=权限1,权限2
[roles]
role1=permission1,permission2

#对web url拦截相关的配置,url=拦截器[参数],拦截器
[urls]
/index.html = anon
/admin/** = authc, roles[admin], perms["permission1"]

上面便是ini配置文件可配置的部分,在程序代码中读取配置文件需要使用代码读取,这里以Java代码为例:

Factory<SecurityManager> factory =
         new IniSecurityManagerFactory("classpath:shiro-config.ini");
SecurityManager securityManager = factory.getInstance();

//将SecurityManager设置到SecurityUtils 方便全局使用
SecurityUtils.setSecurityManager(securityManager);
// 获取当前对象
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
subject.login(token);
// 断言授权
Assert.assertTrue(subject.isAuthenticated());

Java代码

  1. 通过DefaultSecurityManager获取并配置 SecurityManager 。
  2. 配置Authenticator,并设置认证Realm的匹配模式,这里设置至少需要有一个Realm通过认证。
  3. 通过ModularRealmAuthorizer配置授权认证。
  4. 设置Realm的数据源。
  5. 将 SecurityManager 注入到 SecurityUtils 中,以便于在代码中进行使用。
  6. 使用 login 方法进行登录,测试是否登录成功。
    // 获取 SecurityManager
    DefaultSecurityManager securityManager = new DefaultSecurityManager();
    //设置authenticator
    ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
    authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
    securityManager.setAuthenticator(authenticator);
    //设置authorizer
    ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
    authorizer.setPermissionResolver(new WildcardPermissionResolver());
    securityManager.setAuthorizer(authorizer);
    //设置Realm及数据库连接
    DruidDataSource ds = new DruidDataSource();
    ds.setDriverClassName("com.mysql.jdbc.Driver");
    ds.setUrl("jdbc:mysql://localhost:3306/shiro");
    ds.setUsername("root");
    ds.setPassword("");
    JdbcRealm jdbcRealm = new JdbcRealm();
    jdbcRealm.setDataSource(ds);
    jdbcRealm.setPermissionsLookupEnabled(true);
    securityManager.setRealms(Arrays.asList((Realm) jdbcRealm));
    //将SecurityManager设置到SecurityUtils 方便全局使用
    SecurityUtils.setSecurityManager(securityManager);
    Subject subject = SecurityUtils.getSubject();
    UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
    // 登录
    subject.login(token);
    // 断言登录是否成功
    Assert.assertTrue(subject.isAuthenticated());

xml配置文件

在Spring的xml文件中,主要可以配置以下内容:

  1. 配置ShiroFilterFactoryBean:用于创建ShiroFilter,实现对URL的拦截和访问控制。可以配置URL拦截规则、登录URL、认证和授权失败URL、默认的拦截器等信息。

  2. 配置SecurityManager:Shiro的核心管理器,用于管理认证和授权等相关的操作。可以配置Realm、SessionManager、CacheManager等信息,并将其放入Spring的容器中。

  3. 配置AuthenticationStrategy:用于定义认证策略,可以配置多个Realm进行认证,并使用指定的策略进行合并和处理。

  4. 配置Realm:用于提供认证信息的数据源,通常需要实现验证用户名和密码、查询用户角色和权限等操作,可以配置多个Realm。

  5. 配置SessionManager:用于管理用户会话,通常需要实现将用户会话存储到指定的数据源中。

  6. 配置CacheManager:用于缓存Realm中的数据,提高数据查询的效率。

  7. 配置SubjectFactory:用于创建Subject对象,可以自定义Subject对象的Context、Session和SecurityManager等。

  8. 集成Spring EL表达式:可以将Spring EL表达式用于权限字符串的校验,实现更加灵活的授权管理。

在配置完成后,需要将这些配置组合成一个完整的ShiroFilter配置,并放入Spring容器中,以实现Shiro的基本功能。

<!-- 缓存管理器 使用Ehcache实现 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
    <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
</bean>
<!-- 凭证匹配器 -->
<bean id="credentialsMatcher" class="
com.github.zhangkaitao.shiro.chapter12.credentials.RetryLimitHashedCredentialsMatcher">
    <constructor-arg ref="cacheManager"/>
    <property name="hashAlgorithmName" value="md5"/>
    <property name="hashIterations" value="2"/>
    <property name="storedCredentialsHexEncoded" value="true"/>
</bean>
<!-- Realm实现 -->
<bean id="userRealm" class="com.github.zhangkaitao.shiro.chapter12.realm.UserRealm">
    <property name="userService" ref="userService"/>
    <property name="credentialsMatcher" ref="credentialsMatcher"/>
    <property name="cachingEnabled" value="true"/>
    <property name="authenticationCachingEnabled" value="true"/>
    <property name="authenticationCacheName" value="authenticationCache"/>
    <property name="authorizationCachingEnabled" value="true"/>
    <property name="authorizationCacheName" value="authorizationCache"/>
</bean>
<!-- 会话ID生成器 -->
<bean id="sessionIdGenerator" 
class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/>
<!-- 会话DAO -->
<bean id="sessionDAO" 
class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
    <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
    <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
</bean>
<!-- 会话验证调度器 -->
<bean id="sessionValidationScheduler" 
class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
    <property name="sessionValidationInterval" value="1800000"/>
    <property name="sessionManager" ref="sessionManager"/>
</bean>
<!-- 会话管理器 -->
<bean id="sessionManager" class="org.apache.shiro.session.mgt.DefaultSessionManager">
    <property name="globalSessionTimeout" value="1800000"/>
    <property name="deleteInvalidSessions" value="true"/>
    <property name="sessionValidationSchedulerEnabled" value="true"/>
   <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
    <property name="sessionDAO" ref="sessionDAO"/>
</bean>
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.mgt.DefaultSecurityManager">
    <property name="realms">
        <list><ref bean="userRealm"/></list>
    </property>
    <property name="sessionManager" ref="sessionManager"/>
    <property name="cacheManager" ref="cacheManager"/>
</bean>
<!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) -->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" 
value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
    <property name="arguments" ref="securityManager"/>
</bean>
<!-- Shiro生命周期处理器-->
<bean id="lifecycleBeanPostProcessor" 
class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

数据库配置

对于数据库的配置是在SpringBoot项目中对于用户与角色之间的关系、角色与权限之间的关系、权限与访问资源之间的关系是在数据库中进行配置,一般不会保持在ini配置文件中,对于这边设置就不再这里进行阐述,淫威设计道业务逻辑,大家可以参看blog.csdn.net/lvshuocool/…

参考文献:www.w3cschool.cn/shiro/blog.csdn.net/lvshuocool/…