




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Shiro课程目Shiro123shirourl4Shiro5、掌握Shiro进行的常用方法6Shiro权限管什么是权限管管理实现对用户系统的控制按照安全规则或者安全策略控制用户可以而且只能访户首先经过认证,认证通过后用户具有该资源的权限方可。用户认概是系统通过核对用户输入的用户名和口令看其是否与系统中的该用户的用户名和口令用用户是否认通过用户名认证流是是否允问访YES继YES继进行用 认YES继 是否认证通过NO继续认关键对Subject:主箱地址等,一个主体可以有多个,但是必须有一个主(PrimaryPrincipalcredential是只有主体自己知道的安全信息,如、等概,即控制,控制谁能哪些资源。主体进行认证后需要分配权限方可系统的资源,对于某些资源没有权限是无法的。流权限控认权限控认分配权NO系统资继继关键对Who,即主体(Subject),主体需要系统中的资源How,权限/(Permission),规定了主体对资源的操作,权限离开资源没有意义,如用户查询权限、用户添限、某个类方法的调用权限、编号为001用户的修改权限等,通过权限可知主体对哪些资源都有哪些操作。主主(用户权(查询权(添加权(删除权类型商品资(商品信息资权限模主体(账号、)资源(资源名称、地址)********用角权1111****用角1资资源(资源名称、地址)权限(权限名称、资源名称、资源地址*****多对多对1111****权限分权限控用户拥有了权限即可操作权限范围内的资源,系统不知道主体是否具有权限需要对用户的进行控制。基于角色的控RBAC基于角色的控制(Role-BasedAccessControl)是以角色为中心进行控制,比如:主体的角色为总经理可以查询企业运营报表,查询员工工资信息等,控制YESYES查询工资信无无处(通常提示用户无权操作}缺点:以角色进行控制粒度较粗,如果上图中查询工资所需要的角色变化为总经理和if(主体.hasRole("总经理角色id")|| }基于资源的控制,比如:主体必须具有查询工资权限才可以查询员工工资信息等,控制流程如下:}权限管理解决方粗颗粒度和细颗粒什么是粗颗粒度和细颗粒如何实现粗颗粒度和细颗粒service接口添url基于url是企业中常用的权限管理方法,实现思路是:将系统操作的每个url配置在权限表中,将权限对应到角色,将角色分配给用户,用户系统功能通过Filter进行过虑过虑器获取到用户的url只要的url是用户分配角色中的url则放行继续。获 获 Url是否公开地( 地址是否存在url是否公开地Url是否是公地址(只 认 是否存在权限url获 过虑认证过虑系统的资提示无权操放行继放行继放行继放行继 YES认证通NO进行用 认使用权限管理框省系统开发时间,并且权限管理框架提供了完善的认证和功能有利于系统扩展,但基于url实环境准webUI:jqueryeasyUI1.2.2数据mysql5.1导入,先导入shiro_sql_talbe.sql再导入shiro-sql_table_data.sqlactiveUser用户activeUseractiveUsersessionpublicpublicclassActiveUserimplementsjava.io.SerializableprivateStringuserid;//用户idprivateStringusercode;用户账号privateStringusername;privates;privateList<SysPermissionpermissionsanonymousURL.properties公开地址,无需认证即可用户认证filter实现。publicpublicclassLoginInterceptorimplementsHandlerInterceptor在进入controller//使用场景:比 认证校publicbooleanpreHandle(HttpServletRequestHttpServletResponseresponse,Objecthandler)Exception)List<String>open_urls的Stringurl=for(Stringopen_url:open_urls)if(url.indexOf(open_url)>=0)//如 的是公开地址则放return}}HttpSessionsession=ActiveUseractiveUser=(ActiveUser)if(activeUser!=null)return}return}用户使用springmvc器对用户url进行如果用户的url没有分配权限则跳转到无权操作提示页面(refuse.jspfilter实现。publicpublicclassPermissionInterceptorimplementsHandlerInterceptor在进入controller//使用场景:比 认证校进入actionpublicbooleanpreHandle(HttpServletRequestHttpServletResponseresponse,Objecthandler)Exception//TODOAuto-generatedmethod//用 地址Stringurl=)List<String>open_urls//用 的for(Stringopen_url:open_urls)if(url.indexOf(open_url)>=0)//如 的是公开地址则放return}}//从session获取用户公 地址(认证通过无需分配权限即 List<String>common_urls=//用 的for(Stringcommon_url:common_urls)if(url.indexOf(common_url)>=0)//如 的是公共地址则放return}}}//HttpSessionsession=request.getSession();ActiveUseractiveUser=(ActiveUser)取出session中权限List<SysPermission>permission_list=//校验用 地址是否在用户权限范围for(SysPermissionsysPermission:permission_list){Stringpermission_url=sysPermission.getUrl();if(url.contains(permission_url)){return}}request,response);return}用户登url等)activeUsersession。publicStringloginsubmit(HttpSessionsession,Stringpassword,Stringrandomcode)throwsStringvali 错thrownew } 认ActiveUseractiveUser=sysService.authenticat(usercode,session.setAttribute("activeUseractiveUser);return}service接**Title:@param@param@returnActiveUser@throwspublicActiveUserauthenticat(Stringusercode,StringthrowspublicSysUserfindSysuserByUsercode(Stringusercode)根据用户idpublicList<SysPermission>findSysPermissionList(Stringthrows根据用户id shiro介什么为什么要学shiroshiro就可以非常快速shiro。java领域中springsecurity(原名Acegi)也是一个开源的权限管理框架但是springsecurity依赖spring运行shiro就相对独立,最主要是因为shiro使用简单、灵活,所以现在越来shiro。Shiro架Subjectsubject进行交互,subject记录了当前操作用户,将用户的SubjectshirosubjectsubjectSecurityManager责对所有的subject进行安全管理通过SecurityManager可以完成subject的认证等,实质上SecurityManager是通过Authenticator进行认证,通过Authorizer进行,通过SessionManager进行会话管理等。SecurityManagerAuthenticator,Authorizer,SessionManager这三个Authenticator即认证器,对用户进行认证,Authenticator是一个接口,shiro提供ModularRealmAuthenticatorModularRealmAuthenticator基本上可以满足大多Authorizer即器,用户通过认证器认证通过,在功能时需要通过器判断用securityManager注意:realm理解成只是从数据源取数据,在realm中还有认证校验的相关shiro所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点管理,此特性SessionDAO即会话dao,是对session会话操作的一套接口,比如要将session到数据库,可以通过jdbc将会话到数据库。CacheManager即缓存管理,将用户权限数据在缓存,这样可以提高性能Cryptography即管理,shiro提供了一套加密/的组件,方便开发。比如提供用的散列、加/等功能shirojarjavashirojarshiro提供的功能了。shiro-core是包必须选用,还提供了与web整合的shiro-web、与spring整合的shiro-springquartzshiro-quartzshirojarmaven坐标。<artifactId>shiro-<artifactId>shiro-<artifactId>shiro-<artifactId>shiro-<artifactId>shiro-shiro-allshiro<artifactId>shiro-参考 shiro认认证流构构造SecurityManager环提交认执行认执行认根 获取验证信程序(用户登陆和退出java工jdkshiro-coreJar包及依赖log4j.rootLogger=debug, -%mShiro.iniSecurityManager环境。配置eclipseini文件编辑:在eclipse配置后,在classpath创建shiro.ini配置文件,为了方便测试将用户名和配置shiro.ini配置文件中:认证代publicvoidtestLoginLogout()构建SecurityManager工厂,IniSecurityManagerFactory可以从ini文件Factory<SecurityManager>factory=通过工厂创建SecurityManagersecurityManager=将securityManager创建一个Subject实例,该实例认证要使用上边创建的securityManager行行Subjectsubject=创建tokenUsernamePasswordTokentoken=newtry}catch(AuthenticationExceptione)//TODOAuto-generatedcatchblock}BooleanisAuthenticated=System.out.println("用户认证状态:isAuthenticated=System.out.println("用户认证状态:}认证执行流1token令牌,token3AuthenticatorModularRealmAuthenticatorrealmini配置文件取用户真实的账号和,这里使用的是IniRealm(shiro自带)4IniRealmtokenini常见的异 foundforuser。。。。当输入错误会抛此异常,如下: ception:Submitted rememberMe=false]didnotmatchtheexpectedcredentials. ception(凭证过期)等自定上边的程序使用的是Shiro自带的IniRealmIniRealm从ini配置文件中用户的信息,大部分情况下需要从系统的数据库中用户信息,所以需要自定义realm。shiro提供的最基础的是Realm接口,CachingRealm负责缓存处理,AuthenticationRealmAuthorizingRealm负责,通常自定义的realm继承AuthorizingRealm自定publicpublicclassCustomRealm1extendsAuthorizingRealmpublicStringgetName()return}publicbooleansupports(AuthenticationTokentoken)returntokeninstanceof}protectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokentoken)throwsAuthenticationException{//从tokenStringusername=(String)returnreturn}Stringpassword"123";//SimpleAuthenticationInfosimpleAuthenticationInfonewusername,password,return}protectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipals){//TODOAuto-generatedmethodreturn}}# 测试代测试代码同程序,将ini的地址修改为shiro-realm.ini。散列算 转成原始内容散列算法常用于对进行散列常用的散列算法有MD5SHA。一般散列算法需要提供一个salt(盐)与原始内容生成 性,比如:111111的md5值是:96e eb72c92a549dd5a330112,拿着 eb72c92a549dd5a330112”去md5很容易进行,如果要是对111111和salt(盐,一个随机数)进行散列,这样虽然都是111111加不同的盐会生成例Stringpassword_md5newMd5Hash("111111").toString();Stringpassword_md5_sale_1=newMd5Hash("111111","eteokues",Stringpassword_md5_sale_2=newMd5Hash("111111","uiwueylm",StringsimpleHash=newSimpleHash("MD5","111111",realm中使realm从数据库取出盐和加密后的值由shiro完成校验。自定protectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokentoken)throwsAuthenticationException{Stringusername=(String)盐是是Stringpassword=Stringsalt="eteokues";SimpleAuthenticationInfosimpleAuthenticationInfo=username,password,return}realm配. 测试代inishiro流根根获取资源权限信执执方Shiro支持三种方式的编程式:通过写if/else代码块完成Subjectsubject=SecurityUtils.getSubject();if(subject.hasRole(“admin”)){//}else//}Javapublicvoido(){//}JSP/GSP:在JSP/GSP页面通过相应的完成<!本序测试使用第一种编程方式,实际与web系统集成使用后两种方式测 在ini文件中用户、角色、权限的配置规则是用户名=,角色1,角色2...”“角色=12...权限字符串规:”是资源测试代permission.ini publicvoidtestPermission()从ini文件中创建SecurityManagerFactory<SecurityManager>factory=创建SecurityManagersecurityManager=将securityManagerSubjectsubject=
//设置用户认证的 UsernamePasswordTokentoken=newUsernamePasswordToken("zhang",try}catch(AuthenticationExceptione)//TODOAuto-generatedcatchblock}BooleanisAuthenticated=System.out.println("用户认证状态://用 检测基于角System.out.println("用户是否拥有一个角色:System.out.println("用户是否拥有多个角色:"+subject.hasAllRoles(Arrays.asList("role1","role2"))); subject.checkRoles(Arrays.asList("role1", //System.out.println("是否拥有某一个权限:System.out.println("是否拥有多个权限:"+subject.isPermittedAll("user:create:1","user:delete"));}基于角色////用 检测基于角System.out.println("用户是否拥有一个角色:System.out.println("用户是否拥有多个角色:"+subject.hasAllRoles(Arrays.asList("role1","role2")));subject.checkRoles(Arrays.asList("role1",subject.checkRoles(Arrays.asList("role1",上边check方法如果失败则抛出异常org.apache.shiro.authz.UnauthorizedException:Subjectdoesnothaverole 基于资System.out.println("是否拥有某一个权限:System.out.println("是否拥有多个权限:+subject.isPermittedAll("user:create:1",check上边check方法如果失败则抛出异常org.apache.shiro.authz.UnauthorizedException:Subjectdoesnothavepermission 自定realm代realmdoGetAuthorizationInfo方法,此方法需要完成:根据用户从数据库查询权限字符串,由shiro进行。protectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipals){Stringusername=(String)//根 从数据库中查询权限数 List<String>permissions=newArrayList<String>();SimpleAuthorizationInfosimpleAuthorizationInfonewfor(Stringpermission:permissions){}return}ini测试代同上边的测试代码,注意修改ini地址为shiro-realm.ini执行流12securityManagerModularRealmAuthorizer3ModularRealmAuthorizerrealm4ModularRealmAuthorizerpermissionResolvershiro与项目集成开shirospringweb项目整shiro与springweb项目整合在“基于url实现的工程”基础上整合,基于url1、shirospring整合2shiroweb去掉springmvc.xml中配置的LoginInterceptor和PermissionInterceptor器shirojarweb.xmlshiroshirofilter 设置true由servlet容器控制filter设置spring容器filter的beanid,如果不设置则找与filter-name一致 Shiro的Web<bean<propertyname="securityManager"ref="securityManager"loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证--><propertyname="loginUrl"value="/login.action"<propertyname="unauthorizedUrl"value="/refuse.jsp"过虑器链定义,从上向下顺序执行,一般将/**<property<!--退 ,请求logout.action执行退出操作--/logout.action=<!--无 页面--/refuse.jsp=<!--roles[XX]表示有XX角色才 /item/list.action=/js/**/images/**/styles/** .jsp/item/*<!--user表 认证通过或通过记住我认证通过的可/**=<beanid="securityManager"<propertyname="realm"ref="userRealm"realm<beanid="userRealm"的话会自动寻找项目web项目的根 自定此realm先不从数据库查询权限数据,当前需要先将shirorealmpublicpublicclassCustomRealm1extendsAuthorizingRealmpublicStringgetName()return}支持什么类型的tokenpublicbooleansupports(AuthenticationTokentoken)returntokeninstanceof}protectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokentoken)throwsAuthenticationException{从tokenStringusername=(String)拿username//如果查询不到则返回if(!username.equals("zhangreturn}Stringpassword"123"根据用户id s=newSysPermissionsysPermission_1newSysPermission();SysPermissionsysPermission_2newSysPermission();ActiveUseractiveUser=newActiveUser(); 返回认证信息由父类AuthenticatingRealmSimpleAuthenticationInfosimpleAuthenticationInfo=activeUser,password,return}protectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipals){ActiveUseractiveUser=(ActiveUser)Stringuserid=根据用户id List<String>permissions=newArrayList<String>();将权限信息封闭为SimpleAuthorizationInfosimpleAuthorizationInfo=forfor(Stringpermission:permissions){}return}}登publicStringloginsubmit(Modelmodel,HttpServletRequestthrowsExceptionshiro在认证过程中出现错误后将异常类路径通过request返回StringexceptionClassName=(String)request(UnknownAccountException.class.getName().equals(exceptionClassName))thrownewCustomException("账号不存在}else exceptionClassName))thrownewCustomException("用户名 错误elseif("randomCodeError".equals(exceptionClassName)){thrownewCustomException(" }thrownewException();//}}return}首数据通过model到页面。publicStringfirst(Modelmodel)throwsSubjectsubject=ActiveUseractiveUser=(ActiveUser)subject.getPrincipal();model.addAttribute("activeUser",activeUser);return}退,请求logout.action/logout.action=无权当用户无操作权限,shiro将跳转到refuse.jsp页面shiro过虑器总过滤器简 对应的java anon:例子/admins/**=anon没有参数,表示可以使用authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,FormAuthenticationFilter是admins/user/**=n],admins/user/**="admin,guet"],l()方法。isPermitedAll()方法。rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method]methodpost,get,deleteport:例子/admins/user/**=port[8081],url的端口不是8081schemal://serverName:8081?queryString,salhttphttps等,serverName是你的host,8081是url配置里port的端口,queryString是你的url里的?后面的参数authcBasic:例如/admins/user/**=authcBasichttpBasicssl:例子/admins/user/**=sslurluser:例如/admins/user/**=user没有参数表示必须存在用户,认证通过或通过记住我认证通过的可以,当登入操作时不做检查anon,authcBasic,auchc,userperms,roles,ssl,rest,port是过滤认添加凭证匹配md5加密校验。applicationContext-shiro.xml:<bean<propertyname="hashAlgorithmName"value="md5"<property tions"value="1"realm<beanid="userRealm"<propertyname="credentialsMatcher"ref="credentialsMatcher"realm认证方修改realm代码从数据库中查询用户,将sysService注入realmpublicpublicclassCustomRealm1extendsAuthorizingRealmprivateSysServicepublicStringgetName()return}支持什么类型的tokenpublicbooleansupports(AuthenticationTokentoken)returntokeninstanceof}protectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokentoken)throwsAuthenticationException{从tokenStringusercode=(String)SysUsersysUser=null;try{sysUser=}catch(Exceptione)//TODOAuto-generatedcatchblock}if(sysUser==null)return}//根据用户id取出菜单 s=null;try{s= }catch(Exceptione)//TODOAuto-generatedcatchblock}Stringpassword=Stringsalt=ActiveUseractiveUser=newActiveUser(); SimpleAuthenticationInfosimpleAuthenticationInfo=activeUser,password,returnreturn}}8.3修改realm方realmsysServicerealmpublicpublicclassCustomRealm1extendsAuthorizingRealmprivateSysServicepublicStringgetName()return}支持什么类型的tokenpublicbooleansupports(AuthenticationTokentoken)returntokeninstanceof}protectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipals){ActiveUseractiveUser=(ActiveUser)Stringuserid=List<SysPermission>permissions=null;try{permissions=}catch(Exceptione)//TODOAuto-generatedcatchblock} 信SimpleAuthorizationInfosimpleAuthorizationInfo=for(SysPermission}return}}controller开启springmvc.xmlshirocontrollershiro开启aop开启shiro<propertyname="securityManager"ref="securityManager"权限注解控商品查询controller方法添限(item:querypublicModelAndViewqueryItem()throwsException同理,商品修改controller方法添限(item:update(value=(value=publicStringeditItem(@RequestParam(value="id",required=true)Integerid,Modelmodel)throwsExceptionpublicStringeditItemSubmit(@ModelAttribute("item")Itemsitems,BindingResultresult,MultipartFilepictureFile,Modelthrowsjsp控介Jsp<%@tagliburi=""prefix="shiro"名 条件(均是显示内容 登录之 不在登录状态 用户在没有RememberMe 用户在RememberMe<shiro:hasAnyRolesname="abc,123" 在有abc或者123角色<shiro:hasRole 拥有角色<shiro:lacksRole 没有角色<shiro:hasPermission 拥有权限资源<shiro:lacksPermission 没有abc权限资 显示用户名<shiro:principal 显示用户中的属性jsp<shiro:hasPermission<shiro:hasPermissionhref="${pageContext.request.contextPath/item/editItem.action?id=${ite缓shiro每次都会通过realm获取权限信息为了提高速度需要添加缓存第一次从realm中权限数据之后不再这里Shiro和EhcacheEhcachejarapplicationContext-shiro.xml<beanid="securityManager"<propertyname="realm"ref="userRealm"<propertyname="cacheManager"<beanid="cacheManager"<propertyname="cacheManagerConfigFile"value="classpath:shiro-shiro-<<ehcache 地 <diskStorepath="F:\develop\ehcache" 清空缓当用户权限修改后,用户再次登陆shiro会自动调用realm从数据库获取权限数据如果在修改权限后想立即清除缓存则可以调用realm的clearCacherealmclearCachedpublicvoidclearCached(){PrincipalCollectionprincipals=}realmrealmclearCachedsession管<beanid="securityManager"<beanid="securityManager"<propertyname="
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 工伤认定风险点和防范措施
- 2025年五氧化二磷行业政策分析:五氧化二磷行业标准规范行业发展
- 2025年低空雷达行业分析:全球低空雷达市场将达到50亿美元以上
- 云南省昆明市官渡区2024-2025学年高一上学期期末学业水平考试数学试题卷(解析版)
- 渠道穿渠施工方案
- hdpe双壁波纹排水管施工方案
- 管道疏通检测施工方案
- 湿地公园土建施工方案
- 废锅炉拆除施工方案
- 2025年地理预测考试试题及答案
- 护理技术操作考核评分标准患者约束法
- 慢性心功能不全的护理查房
- 电气第一种第二种工作票讲解-课件
- 公司领料单模板
- 药物分析 第05章 体内药物分析
- 山西和顺隆华煤业有限责任公司煤炭资源开发利用和矿山环境保护与土地复垦方案
- 输血与创伤性凝血病
- 人工挖孔桩爆破技术方案
- 2023年牡丹江大学单招面试题库及答案解析
- 矿山工程施工合同施工合同
- 运行程序etops二放手册b787qrh快速检查单
评论
0/150
提交评论