摄影作品网站排行榜,游戏网站织梦模板,搭建平台聚合力,智能家庭app下载目录1.Shro的概念2.Shiro的简单身份认证实现3.Shiro与spring对身份认证的实现前言#xff1a; Shiro 可以非常容易的开发出足够好的应用#xff0c;其不仅可以用在 JavaSE 环境#xff0c;也可以用在 JavaEE 环境。Shiro 可以帮助我们完成#xff1a;认证、授权、加密、会话…目录1.Shro的概念2.Shiro的简单身份认证实现3.Shiro与spring对身份认证的实现 前言 Shiro 可以非常容易的开发出足够好的应用其不仅可以用在 JavaSE 环境也可以用在 JavaEE 环境。Shiro 可以帮助我们完成认证、授权、加密、会话管理、与 Web 集成、缓存等。其强大之处有目共睹但是想要进入Shiro的世界我们必须先要入门这便是一篇入门级别的Shiro教程博客。 一、Shiro的概念 话说“如果一个人只会写代码那么他一辈子都是码农”所以当我们学习一项新技能时先不谈代码把它的概念搞清楚了再搞代码。记住一句话代码只是思想的附属品。 虽然我们这里只讲解身份认证但是我们还是将其概念和功能都介绍一下 1、基本功能 这些就是Shiro的所有基本功能了下面来概括一下它的各项功能—— Authentication身份认证 / 登录验证用户是不是拥有相应的身份 Authorization授权即权限验证验证某个已认证的用户是否拥有某个权限即判断用户是否能做事情常见的如验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限 Session Manager会话管理即用户登录后就是一次会话在没有退出之前它的所有信息都在会话中会话可以是普通 JavaSE 环境的也可以是如 Web 环境的 Cryptography加密保护数据的安全性如密码加密存储到数据库而不是明文存储 Web SupportWeb 支持可以非常容易的集成到 Web 环境 Caching缓存比如用户登录后其用户信息、拥有的角色 / 权限不必每次去查这样可以提高效率 Concurrencyshiro 支持多线程应用的并发验证即如在一个线程中开启另一个线程能把权限自动传播过去 Testing提供测试支持 Run As允许一个用户假装为另一个用户如果他们允许的身份进行访问 Remember Me记住我这个是非常常见的功能即一次登录后下次再来的话不用登录了。 2、Shiro的架构解释 来一张经典的Shiro架构图 这张图是官方给出的Shiro架构图可谓是权威透彻理解了这张图就算对Shiro已经了如指掌了可惜我还没懂—— Subject主体可以看到主体可以是任何可以与应用交互的 “用户” SecurityManager相当于 SpringMVC 中的 DispatcherServlet 或者 Struts2 中的 FilterDispatcher是 Shiro 的心脏所有具体的交互都通过 SecurityManager 进行控制它管理着所有 Subject、且负责进行认证和授权、及会话、缓存的管理。 Authenticator认证器负责主体认证的这是一个扩展点如果用户觉得 Shiro 默认的不好可以自定义实现其需要认证策略Authentication Strategy即什么情况下算用户认证通过了 Authrizer授权器或者访问控制器用来决定主体是否有权限进行相应的操作即控制着用户能访问应用中的哪些功能 Realm可以有 1 个或多个 Realm可以认为是安全实体数据源即用于获取安全实体的可以是 JDBC 实现也可以是 LDAP 实现或者内存实现等等由用户提供注意Shiro 不知道你的用户 / 权限存储在哪及以何种格式存储所以我们一般在应用中都需要实现自己的 Realm SessionManager如果写过 Servlet 就应该知道 Session 的概念Session 呢需要有人去管理它的生命周期这个组件就是 SessionManager而 Shiro 并不仅仅可以用在 Web 环境也可以用在如普通的 JavaSE 环境、EJB 等环境所有呢Shiro 就抽象了一个自己的 Session 来管理主体与应用之间交互的数据这样的话比如我们在 Web 环境用刚开始是一台 Web 服务器接着又上了台EJB 服务器这时想把两台服务器的会话数据放到一个地方这个时候就可以实现自己的分布式会话如把数据放到Memcached 服务器 SessionDAODAO 大家都用过数据访问对象用于会话的 CRUD比如我们想把 Session 保存到数据库那么可以实现自己的 SessionDAO通过如 JDBC 写到数据库比如想把 Session 放到 Memcached 中可以实现自己的 Memcached SessionDAO另外 SessionDAO 中可以使用 Cache 进行缓存以提高性能 CacheManager缓存控制器来管理如用户、角色、权限等的缓存的因为这些数据基本上很少去改变放到缓存中后可以提高访问的性能 Cryptography密码模块Shiro 提高了一些常见的加密组件用于如密码加密 / 解密的。 3、Shiro的工作流程 在这个流程里面我们可以看到API 核心就是 Subject其中各个部分的解释与作用—— Subject主体代表了当前 “用户”这个用户不一定是一个具体的人与当前应用交互的任何东西都是 Subject如网络爬虫机器人等即一个抽象概念所有 Subject 都绑定到SecurityManager与 Subject 的所有交互都会委托给 SecurityManager可以把 Subject 认为是一个门面SecurityManager 才是实际的执行者 SecurityManager安全管理器即所有与安全有关的操作都会与 SecurityManager 交互且它管理着所有 Subject可以看出它是 Shiro 的核心它负责与后边介绍的其他组件进行交互如果学习过 SpringMVC你可以把它看成 DispatcherServlet 前端控制器 Realm域Shiro 从 Realm 获取安全数据如用户、角色、权限就是说 SecurityManager 要验证用户身份那么它需要从 Realm 获取相应的用户进行比较以确定用户身份是否合法也需要从 Realm 得到用户相应的角色 / 权限进行验证用户是否能进行操作可以把 Realm 看成 DataSource即安全数据源。 如果我们写一个最简单的Shiro应用那么大概流程应该是—— 应用代码通过 Subject 来进行认证和授权而 Subject 又委托给 SecurityManager 我们需要给 Shiro 的 SecurityManager 注入 Realm从而让 SecurityManager 能得到合法的用户及其权限进行判断。 二、Shiro的简单身份认证实现 我们要做最简单的Shiro身份认证流程以便于认识Shiro—— 加入依赖 propertiesshiro.version1.4.0/shiro.version /properties dependencyManagement !-- 对shiro的依赖 -- dependency groupIdorg.apache.shiro/groupId artifactIdshiro-core/artifactId version${shiro.version}/version /dependency /dependencies 大概流程为 在Realm中设置数据源。 通过工厂加载配置通过工厂获取安全管理器通过工厂获取Subject对象。 获取验证对象进行验证。 ①设置Realm域Shiro要从Realm域中获取安全、正确的数据。该类必须继承org.apache.shiro.realm.AuthorizingRealm 并重写doGetAuthorizationInfo与doGetAuthenticationInfo方法。doGetAuthorizationInfo是对角色权限的认证这里暂且不详述doGetAuthenticationInfo对用户的认证这里正是我们要详细讲述的地方。代码如下这里暂且模拟数据因为我们要做最简单的流程 1 package org.ssm.service;2 3 4 import org.apache.shiro.authc.AuthenticationException; 5 import org.apache.shiro.authc.AuthenticationInfo; 6 import org.apache.shiro.authc.AuthenticationToken; 7 import org.apache.shiro.authc.SimpleAuthenticationInfo; 8 import org.apache.shiro.authz.AuthorizationInfo; 9 import org.apache.shiro.realm.AuthorizingRealm; 10 import org.apache.shiro.subject.PrincipalCollection; 11 12 /** 13 * 对shiro进行测试的类 14 * author zuoyu 15 * 16 */ 17 public class CustomRealm extends AuthorizingRealm { 18 19 Override 20 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { 21 return null; 22 } 23 24 Override 25 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { 26 // 获取用户的名称信息 27 String userName (String) authenticationToken.getPrincipal(); 28 // 在这里需要从数据库获取信息我们模拟一下即可 29 30 // 验证用户名如果查询不到则返回为空 31 if (!userName.equals(admin)) { 32 return null; 33 } 34 35 // 根据用户名获取从数据库查询到的密码 36 String dbPassWord hello; 37 38 // 返回认证信息由父类AuthenticatingRealm验证 39 SimpleAuthenticationInfo simpleAuthenticationInfo new SimpleAuthenticationInfo( 40 userName, //输入的正确用户名 41 dbPassWord, //对应用户名的正确密码 42 getName() //该方法是父类中的方法不多描述 43 ); 44 return simpleAuthenticationInfo; 45 } 46 47 } ②接着我们要用借用配置文件使securityManager获取到该Realm域配置文件如下 1 [main]
2 #自定义 realm
3 customRealmorg.ssm.service.CustomRealm 4 #将realm设置到securityManager 5 securityManager.realms$customRealm ③万事俱备我们测试一下测试代码如下 1 Test2 public void testShiro() { 3 // 通过工厂加载配置 4 FactorySecurityManager factory new IniSecurityManagerFactory(classpath:shiro-shiro.ini); 5 // 通过工厂获取安全管理器 6 SecurityManager securityManager factory.getInstance(); 7 // 注册Subject工具 8 SecurityUtils.setSecurityManager(securityManager); 9 // 获取Subject对象 10 Subject subject SecurityUtils.getSubject(); 11 // 获取验证对象 12 AuthenticationToken authenticationToken new UsernamePasswordToken(admin, hello); 13 // 验证 14 try { 15 subject.login(authenticationToken); 16 System.out.println(通过... \t authenticationToken.getPrincipal()); 17 } catch (UnknownAccountException e) { 18 System.out.println(未通过:用户不存在 \t authenticationToken.getPrincipal()); 19 e.printStackTrace(); 20 } catch (IncorrectCredentialsException e) { 21 System.out.println(未通过用户密码不正确 \t authenticationToken.getPrincipal()); 22 } catch (LockedAccountException e) { 23 System.out.println(未通过用户被锁定 \t authenticationToken.getPrincipal()); 24 } 25 26 } 是不是很简单呢如果我们运用到实际应用中一般和spring框架结合起来用有了spring的集成用起来更方便 三、Shiro与spring对身份认证的实现 ①我们需要加入依赖 propertiesshiro.version1.4.0/shiro.version /properties dependencyManagement !-- 对shiro的依赖 -- dependency groupIdorg.apache.shiro/groupId artifactIdshiro-core/artifactId version${shiro.version}/version /dependency !-- spring对shiro的支持 -- dependency groupIdorg.apache.shiro/groupId artifactIdshiro-spring/artifactId version${shiro.version}/version /dependency /dependencies ②首先需要配置Shiro的过滤器对所有访问进行过滤需要在web.xml中加上如下配置 !--配置上shiro过滤器使其生效--filter filter-nameshiroFilter/filter-name filter-classorg.springframework.web.filter.DelegatingFilterProxy/filter-class !--设置url由servlet容器控制filter的生命周期-- init-param param-nametransformWsdlLocations/param-name param-valuetrue/param-value /init-param /filter filter-mapping filter-nameshiroFilter/filter-name url-pattern/*/url-pattern /filter-mapping ③我们需要重新定义Realm域且安全数据来源于数据库 1 package org.ssm.shiro.realm;2 3 import org.apache.shiro.authc.*; 4 import org.apache.shiro.authz.AuthorizationInfo; 5 import org.apache.shiro.realm.AuthorizingRealm; 6 import org.apache.shiro.subject.PrincipalCollection; 7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.beans.factory.annotation.Qualifier; 9 import org.ssm.entity.Users; 10 import org.ssm.service.UsersService; 11 12 13 /** 14 * 用户认证 15 * author zuoyu 16 */ 17 public class UserRealm extends AuthorizingRealm { 18 19 /** 20 * 引入users操作的整合操作 21 */ 22 Autowired 23 Qualifier(usersService) 24 private UsersService usersService; 25 26 /** 27 *获取授权信息 28 * param principalCollection 29 * return 30 */ 31 Override 32 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { 33 return null; 34 } 35 36 /** 37 * 获取获取身份验证相关信息 38 * param authenticationToken 39 * return 40 * throws AuthenticationException 41 */ 42 Override 43 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { 44 // 获取用户输入的用户名 45 String userName (String) authenticationToken.getPrincipal(); 46 // 根据用户名查询该数据 47 Users user usersService.selectByName(userName); 48 49 if (user null){ 50 // 没有找到账号 51 throw new UnknownAccountException(); 52 } 53 SimpleAuthenticationInfo authenticationInfo new SimpleAuthenticationInfo(user.getUserName(), user.getPassWord(), 54 // 此为realm内的方法用于获取realm的name 55 getName() 56 ); 57 return authenticationInfo; 58 } 59 } ④需要在spring的applicationContext.xml配置文件加入对Shiro的Bean依赖注入的处理 !--shiro的配置--!--注入自定义的Realm-- bean iduserRealm classorg.ssm.shiro.realm.UserRealm/ bean idsecurityManager classorg.apache.shiro.web.mgt.DefaultWebSecurityManager property namerealm refuserRealm/ /bean !--配置ShiroFilter的属性-- bean idshiroFilter classorg.apache.shiro.spring.web.ShiroFilterFactoryBean property namesecurityManager refsecurityManager/ property namefilterChainDefinitions value /login anon /value /property /bean ⑤写一个springMVC的拦截器对登陆进行拦截 1 package org.ssm.aop;2 3 import org.apache.shiro.SecurityUtils; 4 import org.apache.shiro.subject.Subject; 5 import org.springframework.web.servlet.AsyncHandlerInterceptor; 6 import org.springframework.web.servlet.HandlerInterceptor; 7 import org.springframework.web.servlet.ModelAndView; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 /** 12 * 登陆拦截 13 * author zuoyu 14 */ 15 public class LoginInterceptor implements HandlerInterceptor { 16 17 /** 18 * 登陆拦截 19 * {link AsyncHandlerInterceptor}. 20 * 21 * param request current HTTP request 22 * param response current HTTP response 23 * param handler chosen handler to execute, for type and/or instance evaluation 24 * return {code true} if the execution chain should proceed with the 25 * next interceptor or the handler itself. Else, DispatcherServlet assumes 26 * that this interceptor has already dealt with the response itself. 27 * throws Exception in case of errors 28 */ 29 Override 30 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 31 32 // 从该回话中获取subject 33 Subject subject SecurityUtils.getSubject(); 34 // 获取用户信息 35 String user (String) subject.getPrincipal(); 36 // 如果用户信息为空则进行拦截 37 if (user ! null){ 38 return true; 39 } 40 response.sendRedirect(request.getContextPath() /User/login); 41 return false; 42 } 43 44 45 Override 46 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { 47 48 } 49 50 51 Override 52 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { 53 54 } 55 56 57 } ⑥我们需要在springMVC的配置文件中设置一下该拦截器的拦截对象以及哪些不需要拦截加上如下代码 mvc:interceptorsmvc:interceptor mvc:mapping path/**/ mvc:exclude-mapping path/assets/**/ mvc:exclude-mapping path/User/login/ mvc:exclude-mapping path/logout/ bean classorg.ssm.aop.LoginInterceptor/ /mvc:interceptor /mvc:interceptors ok这样就完成了基于spring集成的简单Shiro身份认证前端页面自己写就可以了。转载于:https://www.cnblogs.com/jianwei-dai/p/8986295.html