作者 : Stanley 罗昊 【转载请注明出处和署名,谢谢!】 *观看本文章需要有一定SpringBoot整合经验* Shiro框架简介 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。使用Shiro的易于理解的API,可以快速、轻松地获得任何应用程序, 从最小的移动应用程序到最大的网络和企业应用程序。 分析Shiro的核心API 其实,Shiro的核心类有三个,分别是: 1.Subject:这个类呢,我们称之当前用户的主体,这个用户的主体包含了登陆、注销等等的一些方法,还有一些判断授权的一些方法; 2.SecurityManager:这个名称翻译过来就是,安全管理器的意思; 3.Realm:这个Realm呢其实我们Shiro去链接数据库的一个桥梁,因为,我们的程序需要去操作数据库去获取一些用户的信息,这些操作都需要Realm去完成; 这个三个API呢,都存在一些关系,比如.SecurityManager是需要去关联我们的Realm,Subject是需要把操作交给我们的SecurityManager,总结下来就是,Subject是需要去管理我们的SecurityManager,而SecurityManager去关联我们的Realm; 以上就是对Shiro的核心API进行的一些分析; 分析完之后,我们接下来就直接用SpringBoot与Shiro的整合,我们来看下它整合的关键步骤 SpringBoot整合Shiro 那么这个整合首先第一步需要导入Shiro的依赖; 【因为我用的是Gradle,所以仅展示Gradle用法】 1.修改.gradle文件,添加以下依赖 复制代码 //Thymeleaf模板引擎,因为我用模板引擎所以我添加了此依赖 compile group: 'org.thymeleaf', name: 'thymeleaf', version: '3.0.11.RELEASE' //Shiro compile group: 'org.apache.shiro', name: 'shiro-web', version: '1.4.0' compile group: 'org.apache.shiro', name: 'shiro-core', version: '1.4.0' // https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring compile group: 'org.apache.shiro', name: 'shiro-spring', version: '1.4.0' 复制代码 2.编写Shiro的配置类 配置类需要三样API,分别是: 复制代码 /** * 创建ShiroFilterFactoryBean * shiro过滤bean */ /** * 创建DefaultWebSecurityManager */ /** * 创建Realm */ 复制代码 如图: 3.自定义Realm类 因为我们需要在配置类中创建出Realm对象,所以我们需要建一个名为Realm的类: 创建后,需要继承一个方法,这个方法是Shiro提供的: 复制代码 /** * 自定义Realm */ public class UserRealm extends AuthorizingRealm { //执行授权逻辑 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { return null; } //执行认证逻辑 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException { return null; } 复制代码 4.在配置类中new出Realm Shiro配置配置类 复制代码 package com.lh.shiroStudy.shiro; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.LinkedHashMap; import java.util.Map; /** * Shiro配置类 */ //@Configuration,声明本类是一个配置类 @Configuration public class ShiroConfig { /** * 创建ShiroFilterFactoryBean * shiro过滤bean */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); //设置安全管理器 shiroFilterFactoryBean.setSecurityManager(securityManager); //添加Shiro过滤器 /** * Shiro内置过滤器,可以实现权限相关的拦截器 * 常用的过滤器: * anon: 无需认证(登录)可以访问 * authc: 必须认证才可以访问 * user: 如果使用rememberMe功能可以直接访问 * perms: 该资源必须得到资源权限才可以访问 * role: 该资源必须得到角色权限才可以访问 */ MapfilterMap = new LinkedHashMap(); //左边编写拦截路径 filterMap.put("/add","authc"); filterMap.put("/update","authc"); filterMap.put("/testThymeleaf","authc"); //授权过滤器 //注意:当前授权拦截后,shiro会自动跳转未授权页面 filterMap.put("/add","perms[user:add]"); //修改跳转的登陆页面 shiroFilterFactoryBean.setLoginUrl("/toLogin"); //转跳至未授权页面【友好提示】 shiroFilterFactoryBean.setUnauthorizedUrl("/aaaaaa");//懒省事所以没有aaaa这个页面,如果需要,请在Contoller中添加 shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap); return shiroFilterFactoryBean; } /** * 创建DefaultWebSecurityManager */ @Bean(name = "securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("UserRealm") UserRealm userRealm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(userRealm); return securityManager; } /** * 创建Realm */ @Bean(name = "UserRealm") public UserRealm getRealm(){ return new UserRealm(); } } 复制代码 Realm类 复制代码 package com.lh.shiroStudy.shiro; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; /** * 自定义Realm */ public class UserRealm extends AuthorizingRealm { //执行授权逻辑 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { //给资源进行授权 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //添加资源的授权字符串 //info.addStringPermission("user:add"); //到数据库查询当前登陆用户的授权字符串 /** * * 获取当前用户 * Subject subject = SecurityUtils.getSubject(); * User user = (User)subject.getPrincipal(); * User dbUser = userService.findById(id) * info.addStringPermission(dbUser.getPerms()); * */ System.out.println("执行授权逻辑"); return null; } //执行认证逻辑 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException { System.out.println("执行认证逻辑"); //假设数据库账号与密码是如下 String username = "admin"; String password = "123456"; /** * 编写Shiro判断逻辑,比对用户名和密码 */ //1.判断用户名 UsernamePasswordToken token =(UsernamePasswordToken)arg0; //User user = userService.findByName(token.getUsername()); if (user == null){ //用户名不存在 return null;//如果返回null,Shiro底层会抛出UnknowAccountException } //2.判断密码 /** * 有三个参数 * 1.需要返回给login * 2.是数据库的密码,将数据库密码返回,Shiro会自动判断 * 3.是Shiro的名字 */ return new SimpleAuthenticationInfo(user,password,""); } } 复制代码 作者:罗昊 感谢各位阅读学习, 如果有疑问或纠错请在评论区留言与我交流,再次感谢各位读者的支持https://www.cnblogs.com/StanleyBlogs/p/11407350.html