`

Apache Shiro 整合Spring 进行权限验证

阅读更多

Apache Shiro是什么? 
Apache Shiro是一个功能强大且易于使用的Java安全框架,进行认证,授权,加密和会话管理。随着Shiro的易于理解的API,你可以快速,轻松地确保任何应用程序 - 移动应用从最小的到最大的Web和企业应用。 
如何使用Apache Shiro(这里指与Spring 集成)? 
1. 首先去官方网站下载相关jar包(这里使用1.2.2版本),其中包括: 
shiro-core-1.2.2.jar 
shiro-spring-1.2.2.jar 
shiro-web-1.2.2.jar 
(还需要slf4j相关jar支持) 
2.在web.xml中配置shiroFilter(注意这个filter一定要放在所有的filter之前,否则不能成功使用)
 


3.创建一个applicationContext-shiro.xml,对shiro进行配置,内容如下: 

Java代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xmlns:aop="http://www.springframework.org/schema/aop"  
  5.        xmlns:tx="http://www.springframework.org/schema/tx"  
  6.        xmlns:util="http://www.springframework.org/schema/util"  
  7.        xmlns:context="http://www.springframework.org/schema/context"  
  8.        xsi:schemaLocation="  
  9.        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
  10.        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd  
  11.        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd  
  12.        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd  
  13.        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  
  14.     <!-- =========================================================  
  15.          Shiro Components  
  16.          ========================================================= -->  
  17.   
  18.     <!-- Shiro's main business-tier object for web-enabled applications  
  19.          (use org.apache.shiro.web.mgt.DefaultWebSecurityManager instead when there is no web environment)-->  
  20.     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  21.         <!-- Single realm app (realm configured next, below).  If you have multiple realms, use the 'realms'  
  22.       property instead. -->  
  23.     <!--这里的sampleRealm需要我们自己实现,主要包括2个方法  
  24. 1.  用户登录的验证(授权)  
  25. 2.  用户具有的角色和权限(认证)  
  26.  且看下面介绍-->  
  27.         <property name="realm" ref="sampleRealm"/>  
  28.         <!-- Uncomment this next property if you want heterogenous session access or clusterable/distributable  
  29.              sessions.  The default value is 'http' which uses the Servlet container's HttpSession as the underlying  
  30.              Session implementation.  
  31.         <property name="sessionMode" value="native"/> -->  
  32.     </bean>  
  33.   
  34.     <!-- Post processor that automatically invokes init() and destroy() methods -->  
  35.     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>  
  36.     <!-- 自定义角色过滤器 支持多个角色可以访问同一个资源 eg:/home.jsp = authc,roleOR[admin,user]  用户有admin或者user角色 就可以访问-->  
  37.      <bean id="roleOR" class="com.yale.app.security.OneRoleAuthorizationFilter"/>  
  38.     <!-- Define the Shiro Filter here (as a FactoryBean) instead of directly in web.xml -  
  39.          web.xml uses the DelegatingFilterProxy to access this bean.  This allows us  
  40.          to wire things with more control as well utilize nice Spring things such as  
  41.          PropertiesPlaceholderConfigurer and abstract beans or anything else we might need: -->  
  42.     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  43.         <property name="securityManager" ref="securityManager"/>  
  44.         <property name="loginUrl" value="/page/login.jsp"/>  
  45.         <property name="successUrl" value="/page/index.jsp"/>  
  46.         <property name="unauthorizedUrl" value="/register/unauthorized"/>  
  47.         <!-- The 'filters' property is usually not necessary unless performing an override, which we  
  48.              want to do here (make authc point to a PassthruAuthenticationFilter instead of the  
  49.              default FormAuthenticationFilter: -->  
  50.         <property name="filters">  
  51.             <util:map>  
  52.                 <entry key="authc">  
  53.                     <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter"/>  
  54.                 </entry>  
  55.             </util:map>  
  56.         </property>  
  57.         <property name="filterChainDefinitions">  
  58.             <value>  
  59.                 /page/login.jsp = anon  
  60.                 /page/register/* = anon  
  61.                 /page/index.jsp = authc   
  62.                 /page/addItem* = authc,roles[数据管理员]  
  63.                 /page/file* = authc,roleOR[数据管理员,普通用户]  
  64.                 /page/listItems* = authc,roleOR[数据管理员,普通用户]  
  65.                 /page/showItem* = authc,roleOR[数据管理员,普通用户]  
  66.                 /page/updateItem*=authc,roles[数据管理员]  
  67.             </value>  
  68.         </property>  
  69.     </bean>  
  70.   
  71. </beans>  


其中的定义官网文档有详细的解释,这里不做描述! 
然后在applicationContext.xml中引入该文件! 

3. 实现sampleRealm,继承AuthorizingRealm,并重写认证授权方法 
1) 我们首先创建两张表User,Role(这里只做最简单的基于用户-角色的权限验证,如果需要细粒度的控制,自己在添加权限表Permissions然后进行关联操作)
 

Java代码  收藏代码
  1. DROP TABLE IF EXISTS `users`;  
  2. CREATE TABLE `users` (  
  3.   `userid` int(10) NOT NULL AUTO_INCREMENT,  
  4.   `loginName` varchar(16) DEFAULT NULL,  
  5.   `password` varchar(16) DEFAULT NULL,  
  6.   `mail` varchar(50) DEFAULT NULL,  
  7.   `roleid` int(10) NOT NULL,  
  8.   PRIMARY KEY (`userId`),  
  9.   KEY `RoleId` (`roleid`),  
  10.   CONSTRAINT `users_ibfk_1` FOREIGN KEY (`roleid`) REFERENCES `roles` (`RoleId`)  
  11. ) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8;  
  12. DROP TABLE IF EXISTS `roles`;  
  13. CREATE TABLE `roles` (  
  14.   `roleid` int(10) NOT NULL,  
  15.   `roleName` varchar(50) DEFAULT NULL,  
  16.   PRIMARY KEY (`RoleId`)  
  17. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  
  18. --插入测试数据  
  19. INSERT INTO `roles` VALUES ('1''普通用户');  
  20. INSERT INTO `roles` VALUES ('2''数据管理员');  
  21. INSERT INTO `users` VALUES ('1''yale''123456''yale@126.com''1');  
  22. INSERT INTO `users` VALUES ('2''admin''admin''admin@126.com''2');  
  23. 然后,创建对应的实体类,Dao操作,Service。这里不做细述  


接下来我们看sampleRealm具体内容: 

Java代码  收藏代码
  1. import org.apache.shiro.SecurityUtils;  
  2. import org.apache.shiro.authc.AuthenticationException;  
  3. import org.apache.shiro.authc.AuthenticationInfo;  
  4. import org.apache.shiro.authc.AuthenticationToken;  
  5. import org.apache.shiro.authc.SimpleAuthenticationInfo;  
  6. import org.apache.shiro.authc.UsernamePasswordToken;  
  7. import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher;  
  8. import org.apache.shiro.authz.AuthorizationInfo;  
  9. import org.apache.shiro.authz.SimpleAuthorizationInfo;  
  10. import org.apache.shiro.realm.AuthorizingRealm;  
  11. import org.apache.shiro.session.Session;  
  12. import org.apache.shiro.subject.PrincipalCollection;  
  13. import org.springframework.beans.factory.annotation.Autowired;  
  14. import org.springframework.stereotype.Component;  
  15.   
  16. import com.yale.app.service.UserOperator;  
  17. import com.yale.app.model.Role;  
  18. import com.yale.app.model.User;  
  19.   
  20. /** 
  21.  * The Spring/Hibernate sample application's one and only configured Apache Shiro Realm. 
  22.  * 
  23.  * <p>Because a Realm is really just a security-specific DAO, we could have just made Hibernate calls directly 
  24.  * in the implementation and named it a 'HibernateRealm' or something similar.</p> 
  25.  * 
  26.  * <p>But we've decided to make the calls to the database using a UserDAO, since a DAO would be used in other areas 
  27.  * of a 'real' application in addition to here. We felt it better to use that same DAO to show code re-use.</p> 
  28.  */  
  29. @Component  
  30. public class SampleRealm extends AuthorizingRealm {  
  31.       
  32.      @Autowired  
  33.      private UserOperator userOperator;  
  34.   
  35.     public SampleRealm() {  
  36.         setName("SampleRealm"); //This name must match the name in the User class's getPrincipals() method  
  37.       //  setCredentialsMatcher(new Sha256CredentialsMatcher());  
  38.         setCredentialsMatcher(new AllowAllCredentialsMatcher());  
  39.     }  
  40.   
  41.      
  42. //认证信息,主要针对用户登录,(下文讲述在action或者controller登录过程代码)  
  43.     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {  
  44.         UsernamePasswordToken token = (UsernamePasswordToken) authcToken;  
  45.         
  46.         String  password = String.valueOf(token.getPassword());  
  47. //调用操作数据库的方法查询user信息  
  48.         User user = userOperator.login( token.getUsername());  
  49.         if( user != null ) {  
  50.             if(password.equals(user.getPassword())){  
  51.                   Session session= SecurityUtils.getSubject().getSession();  
  52.                   session.setAttribute("username", user.getLoginName());  
  53.             return new SimpleAuthenticationInfo(user.getUserId(), user.getPassword(), getName());  
  54.             }else{  
  55.                 return null;  
  56.             }  
  57.         } else {  
  58.             return null;  
  59.         }  
  60.     }  
  61. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
  62.         String userId = (String) principals.fromRealm(getName()).iterator().next();  
  63.         User user = userOperator.getById(userId);  
  64.         if( user != null ) {  
  65.             SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
  66.            Role role = userOperator.getByRoleId(user.getRoleId());  
  67.                 info.addRole(role.getRoleName());  
  68.               //  info.addStringPermissions( role.getPermissions() );//如果你添加了对权限的表,打开此注释,添加角色具有的权限  
  69.               
  70.             return info;  
  71.         } else {  
  72.             return null;  
  73.         }  
  74.     }  
  75.   
  76. }  


--注意shiro配置文件中 
<bean id="roleOR" class="com.yale.app.security.OneRoleAuthorizationFilter"/> 
OneRoleAuthorizationFilter:为验证多个角色可以访问同一个资源的定义:
 

Java代码  收藏代码
  1. import java.io.IOException;  
  2. import java.util.Set;  
  3.   
  4. import javax.servlet.ServletRequest;  
  5. import javax.servlet.ServletResponse;  
  6.   
  7. import org.apache.shiro.subject.Subject;  
  8. import org.apache.shiro.util.CollectionUtils;  
  9. import org.apache.shiro.web.filter.authz.AuthorizationFilter;  
  10.   
  11. public class OneRoleAuthorizationFilter extends AuthorizationFilter{  
  12.   
  13.      @SuppressWarnings({"unchecked"})  
  14.         public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {  
  15.   
  16.             Subject subject = getSubject(request, response);  
  17.             String[] rolesArray = (String[]) mappedValue;  
  18.   
  19.             if (rolesArray == null || rolesArray.length == 0) {  
  20.                 //no roles specified, so nothing to check - allow access.  
  21.                 return true;  
  22.             }  
  23.             boolean flag = false;  
  24.             Set<String> roles = CollectionUtils.asSet(rolesArray);  
  25.             for (String string : roles) {  
  26.                 if(subject.hasRole(string)){  
  27.                     flag = true;  
  28.                 }  
  29.             }  
  30.             return flag;  
  31.         }  
  32.   
  33. }  


4. 在工程WebRoot/page下,创建login.jsp,index.jsp,register.jsp; 
这里主要说明index.jsp 
Shiro具有自己的JSP / GSP Tag Library,用户做权限检查判断等等 
所以我们在index.jsp引入shiro 标签库 

 
里面用很多的标签,这里我们主要说明: 

 
如果用户具有administrator 角色我们就给他显示这个链接 

 
如果用户有user:create权限 我们显示此链接 
根据我上文提到的user和role表中的数据,我们在index.jsp,做如下测试: 
<shiro:hasRole name="数据管理员”> 
您好管理员同志! 
    </shiro:hasRole> 
<shiro:hasRole name="普通用户”> 
您好普通用户! 
    </shiro:hasRole> 
5. jsp页面写完后,接下来我们看UserAction(用户登录,退出等操作): 

Java代码  收藏代码
  1. //登录  
  2.         public String login(){  
  3. UsernamePasswordToken token = new UsernamePasswordToken(user.getName(), user.getPassword());  
  4.         try {  
  5.             SecurityUtils.getSubject().login(token);  
  6.                   
  7.         } catch (AuthenticationException e) {  
  8.             redirectPath="/page/login.jsp";  
  9.             return "redirect";  
  10.         }  
  11.         redirectPath="/page/index.jsp";  
  12.         return "redirect";  
  13.     }  
  14. //注销  
  15.     public String loginout(){  
  16.         SecurityUtils.getSubject().logout();  
  17.          redirectPath="/login.jsp";  
  18.             return "redirect";  
  19.     }  


至此基本结束,启动项目,就可以体验shiro的安全控制了 嘿嘿 

下面说freemarker中使用shiro标签 
这个网上一搜索就能找到答案,已经由James Gregory把代码上传到GitHub, 
地址:https://github.com/jagregory/shiro-freemarker-tags 
下载该jar包 或者源代码文件复制到自己工程的lib下或者package中 
我是讲文件复制到自己的package中使用: 


 

如果你使用spring MVC 
请看http://www.woxplife.com/articles/473.html 
如果你单独使用Freemarker 比如使用模板生成静态页 
在相关的类中加入如下代码: 
Configuration cfg = new Configuration(); 
cfg.setDefaultEncoding(“UTF-8”); 
cfg.setSharedVariable("shiro", new ShiroTags()); 
然后在ftl页面中使用tag: 
<@shiro.hasRole name=”admin”>Hello admin!</@shiro.hasRole> 
如果是使用struts2集成的freemarker作为页面渲染 
可以写一个类extend    Struts2的FreemarkerManager: 

Java代码  收藏代码
  1. import javax.servlet.ServletContext;     
  2.      
  3. import org.apache.struts2.views.freemarker.FreemarkerManager;     
  4.      
  5. import freemarker.template.Configuration;     
  6. import freemarker.template.TemplateException;     
  7.      
  8. public class MyFreemarkerManager extends FreemarkerManager {     
  9.      
  10.     @Override     
  11.     protected Configuration createConfiguration(ServletContext servletContext) throws TemplateException {     
  12.         Configuration cfg = super.createConfiguration(servletContext);     
  13.        cfg.setSharedVariable("shiro"new ShiroTags());  
  14.         return cfg;     
  15.     }     
  16. }  


然后在struts.xml中指定struts使用我们自己扩展的 FreemarkerManager 
<constant name="struts.freemarker.manager.classname"   
    value="com.xxx.xxx.MyFreemarkerManager" />  
然后在页面中 
然后在ftl页面中使用tag: 
<@shiro.hasRole name=”admin”>Hello admin!</@shiro.hasRole> 

 

----------------------------shiro内置过滤器研究-------------------------------------------

anon org.apache.shiro.web.filter.authc.AnonymousFilter
authc org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authcBasic
org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
perms
org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
port
org.apache.shiro.web.filter.authz.PortFilter
rest
org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
roles
org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
ssl org.apache.shiro.web.filter.authz.SslFilter
user org.apache.shiro.web.filter.authc.UserFilter

 

rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。
port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString
是你访问的url里的?后面的参数。
perms:例子/admins/user/**=perms[user:add:*],perms参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于
isPermitedAll()方法。
roles:例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如/admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。
anon:例子/admins/**=anon 没有参数,表示可以匿名使用。
authc:例如/admins/user/**=authc表示需要认证才能使用,没有参数
authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证
ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
 
这些过滤器分为两组,一组是认证过滤器,一组是授权过滤器。其中anon,authcBasic,auchc,user是第一组,
perms,roles,ssl,rest,port是第二组
 

 

分享到:
评论

相关推荐

    Apache Shiro 集成-spring

    3. Shiro与Spring MVC的整合:配置ShiroFilter,使其作为Spring MVC的拦截器运行。 4. 安全注解:利用@RequiresAuthentication、@RequiresRoles、@RequiresPermissions等注解进行权限控制。 5. 会话管理:可以配置...

    shiro整合spring项目实例

    总结,这个"shiro整合spring项目实例"涵盖了Shiro与Spring的整合流程,包括核心组件配置、Realm实现、过滤器链设定、权限管理、Session操作以及测试验证。通过这个实例,开发者能够更好地理解和掌握Shiro在实际项目...

    shiro整合spring+springmvcjar包

    将Shiro 整合到Spring 和 Spring MVC 中,可以实现统一的身份验证和授权管理,简化安全控制逻辑。 1. **Shiro 基本概念**: - **认证(Authentication)**:验证用户身份的过程,即确认用户是谁。 - **授权...

    apache shiro整合struts2+spring+mybatis简单demo

    在这个“apache shiro整合struts2+spring+mybatis简单demo”中,我们将探讨如何将Shiro与三个流行的Java开发框架——Struts2、Spring和MyBatis进行集成,构建一个完整的安全管理体系。 首先,Struts2是一个基于MVC...

    spring mvc整合shiro登录 权限验证实例下载

    本文将详细介绍如何整合Spring MVC与Shiro进行用户登录、注销以及权限验证的实例。 首先,Spring MVC是Spring框架的一部分,它提供了一种模型驱动的开发方式,使得开发者可以更方便地构建RESTful的Web服务。它的...

    SpringBoot + Apache Shiro1.9.1 最新版本详细教程,基于RBAC角色访问、安全管理框架、用户角色权限

    4、优点:快速上手、全面支持验证、授权、加密和会话、灵活自定义设计、支持web环境、可以无缝集成spring等优点。可以用来用户验证、用户授权、用户session管理、安全加密等 5、基于RBAC五张表:用户表 tb_user、...

    Apache Shiro教程

    - **Spring整合**:Shiro可以无缝集成到Spring应用中,利用Spring的依赖注入管理Shiro组件。 - **Web框架集成**:如Struts、Spring MVC等,通过拦截器实现Shiro的安全控制。 7. **学习资源** - **官方文档**:...

    spring shiro整合

    在IT行业中,Spring Shiro整合是一项常见的安全框架搭建技术,主要应用于Java Web开发。Spring MVC作为主流的MVC框架,负责处理HTTP请求和业务逻辑,MyBatis则为持久层框架,负责数据库交互,而Apache Shiro则是一个...

    shiro和spring整合

    Apache Shiro 和 Spring 的整合是Java Web开发中常见的安全框架集成方式,这使得开发者能够利用Shiro的强大安全功能,同时享受Spring的灵活架构优势。在本文中,我们将深入探讨Shiro与Spring整合的关键知识点,包括...

    shiro+spring的Demo

    在Java Web开发领域,Apache Shiro和Spring框架的结合使用已经成为一种常见的安全解决方案。本示例项目"shiro+Spring的Demo"旨在展示如何将这两个强大的工具集整合,以实现高效、灵活的身份认证和授权功能。项目基于...

    Shiro和Spring整合 这个资源真的可运行

    Apache Shiro 和 Spring 的整合是 Java Web 开发中常见的安全框架集成方式,它们结合可以提供强大的权限管理和认证功能。Shiro 是一个轻量级的安全框架,而 Spring 是一个全面的企业级应用开发框架,两者整合能使得...

    Spring MVC+Mybatis+Ehcache+Apache Shiro+Bootstrap整合开发java仓库管理系统源码

    这是一个基于Java技术栈的仓库管理系统源码,使用了Spring MVC作为MVC框架,Mybatis作为持久层框架,Ehcache作为缓存管理工具,Apache Shiro进行权限控制,以及Bootstrap作为前端UI框架。下面将详细解析这些技术在...

    shiro_spring_velocity整合

    在 Spring 框架中整合 Shiro,首先需要在 `pom.xml` 文件中添加 Shiro 的依赖。接着,在 `Web.xml` 中配置 Shiro 过滤器,使用 `DelegatingFilterProxy` 来代理 Shiro 的 Filter,确保 Shiro 能够访问 Spring 容器...

    Shiro整合Spring

    Apache Shiro 是一个强大且易用的 Java 安全框架,提供了认证、授权、加密和会话管理功能,可以非常方便地与 Spring 框架进行整合,为我们的应用程序提供全面的安全控制。在这个"Shiro 整合 Spring"的主题中,我们将...

    shirodemo整合spring+springmvc+shiro

    4. **定义安全 Realm**:Realm 是Shiro中的核心组件,负责用户身份验证和权限验证。我们需要自定义一个 Realm 类,实现`AuthorizingRealm`接口,覆盖`doGetAuthenticationInfo`和`doGetAuthorizationInfo`方法,对接...

    spring shiro整合入门

    Spring Shiro 整合入门教程 ...最后,通过不断实践和学习,你将更深入地理解Spring Shiro整合的细节,从而更好地应用在实际项目中。参考链接中的博客文章会有更具体的步骤和示例代码,帮助你进一步掌握这一技术。

    shiro与spring整合

    Apache Shiro 和 Spring 的整合是企业级应用中常见的安全框架集成方式,这使得开发者能够利用 Shiro 强大的权限管理功能,同时享受 Spring 提供的依赖注入和事务管理等服务。下面将详细介绍这个整合过程中的关键知识...

    SpringBoot与Shiro整合-权限管理实战源码.zip

    下面我们将详细探讨SpringBoot与Shiro整合实现权限管理实战中的关键知识点。 1. **SpringBoot简介** SpringBoot是由Pivotal团队提供的全新框架,旨在简化Spring应用的初始搭建以及开发过程。它通过“约定优于配置...

    shiro+spring+data+session+redis实现单点登录

    在SSO中,Spring可以帮助整合各种组件,如Shiro和Spring Data,同时管理会话状态。 **Spring Data** Spring Data是Spring的一个模块,它简化了数据访问层的开发,支持多种数据存储技术,如JPA、MongoDB、Redis等。...

    shiro最简单整合版本

    在本文中,我们将深入探讨 Apache Shiro 的核心概念及其最简单的整合方式。 一、Shiro 的核心组件 1. 身份认证(Authentication):这是验证用户身份的过程,通常涉及用户名和密码的输入。Shiro 提供了 Realm 接口...

Global site tag (gtag.js) - Google Analytics