在学习shiro中遇到很多问题,网上资料较少,只有硬啃英文,但demo太少,不好理解。ITeye博客中开涛对编写了比较全的系列教程
跟我学Shiro目录贴
,提供给大家学习,感谢开涛。
在学习到第十三章 RememberMe——《跟我学Shiro》的时候,有一个问题困扰了我2天,给开涛留言,至今未回复,功夫不复有心人,今天早上得到了解决。
问题描述:
1.按照开涛的测试过程
1、访问http://localhost:8080/chapter13/,会跳转到登录页面,登录成功后会设置会话及rememberMe Cookie;
2、关闭浏览器,此时会话cookie将失效;
3、然后重新打开浏览器访问http://localhost:8080/chapter13/,还是可以访问的;
4、如果此时访问http://localhost:8080/chapter13/authenticated.jsp,会跳转到登录页面重新进行身份验证。
测试本章节demo时发现记住我功能不能实现,仔细思考为什么呢?
2.查看cookie,仅生成了sid的cookie,没有生成rememberMe,究竟哪里出了问题?
3.debug跟踪源码
public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException { AuthenticationInfo info; try { info = authenticate(token); } catch (AuthenticationException ae) { try { onFailedLogin(token, ae, subject); } catch (Exception e) { if (log.isInfoEnabled()) { log.info("onFailedLogin method threw an " + "exception. Logging and propagating original AuthenticationException.", e); } } throw ae; //propagate } Subject loggedIn = createSubject(token, info, subject); onSuccessfulLogin(token, info, loggedIn); return loggedIn; }
从onSuccessfulLogin(token, info, loggedIn);这里一路逛追,直至
private javax.crypto.Cipher newCipherInstance(boolean streaming) throws CryptoException { String transformationString = getTransformationString(streaming); try { return javax.crypto.Cipher.getInstance(transformationString); } catch (Exception e) { String msg = "Unable to acquire a Java JCA Cipher instance using " + javax.crypto.Cipher.class.getName() + ".getInstance( \"" + transformationString + "\" ). " + getAlgorithmName() + " under this configuration is required for the " + getClass().getName() + " instance to function."; throw new CryptoException(msg, e); } }
在这里 return javax.crypto.Cipher.getInstance(transformationString);抛出异常:
org.apache.shiro.crypto.CryptoException: Unable to acquire a Java JCA Cipher instance using javax.crypto.Cipher.getInstance( "AES/CBC/PKCS5Padding" ). AES under this configuration is required for the org.apache.shiro.crypto. AesCipherService instance to function. ...... Caused by: java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/CBC/PKCS5Padding at javax.crypto.Cipher.getInstance(Cipher.java:523) at org.apache.shiro.crypto.JcaCipherService.newCipherInstance (JcaCipherService.java:408) ... 28 more
4.不明觉历!!!!!!!!!!!难道是开涛的代码有问题??还是故意设置了障碍要大家学习(实践证明这些假设都是错的)
5.网上查了很多资料,未果,分析源码CookieRememberMeManager继承了AbstractRememberMeManager,在AbstractRememberMeManager中的构造方法中默认初始化了加密算法与设置了默认的cipherKey
public AbstractRememberMeManager() { this.serializer = new DefaultSerializer<PrincipalCollection>(); this.cipherService = new AesCipherService(); setCipherKey(DEFAULT_CIPHER_KEY_BYTES); }
问题的结点可以定在cipherService的实现或者cipherKey的配置上,但很快排除了这一假设。
6.回顾第5章节的例子
@Test public void testAesCipherService() { CipherService cipherService = new AesCipherService(); // aesCipherService.setKeySize(128);//设置key长度 // byte[] key = aesCipherService.generateNewKey().getEncoded(); // String base64 = Base64.encodeToString(key); byte[] key = Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="); System.out.println("key2==" + key.toString()); System.out.println(Base64.encodeToString(key)); // 生成key // Key key = aesCipherService.generateNewKey(); String text = "hello"; System.out.println(new String(text.getBytes())); // 加密 try { String encrptText = cipherService.encrypt(text.getBytes( ), key).toHex(); System.out.println("encrptText==" + encrptText); // 解密 String text2 = new String(cipherService.decrypt( Hex.decode(encrptText), key).getBytes()); System.out.println("text2==" + text2); Assert.assertEquals(text, text2); } catch (CryptoException e) { e.printStackTrace(); } }
不断调试,右击项目属性--Properties----Java Build Path-----Libraries----JRE System Libraries,修改为jdk_1.7.0.01_x86(名称是添加jre时自定义的),测试代码,可以运行通过。原来是jdk的设置不正确!!!!我的电脑上安装了x86,x64的jdk,平时使用的是x64的版本。
7.以为大功告成,可是……使用jetty启动、使用tomcat启动,测试失败!啊啊啊!!要疯的节奏
8.难道是环境变量也要改过来?修改jdk环境变量%JAVA_HOME%为x86的版本之后,测试成功!终于松了一口气。
记录此问题的解决过程,虽然仅仅是jdk版本的问题,可能安装了x86 jdk的人永远不会遇到,但是还是费了我不少功夫去排除道道屏障,最终拨云见日。
结论:
1.shiro的加密使用javax.crypto.Cipher.getInstance获得实例,不支持64bit的jdk
2.遇到这个错误不用改环境变量,可以通过配置运行时的jre解决
a)tomcat:window->perferences->server->runtime Env--Edit Server--修改JRE为x86版本
b)jetty:Debug As--Run Configurations---JRE修改为x86版本
(此问题为电脑上同时安装了x64、x86版本jdk的伙伴记录)
相关推荐
***txt文件中含有下载地址** 《跟我学Shiro》- 张开涛,PDF版本,带目录,清晰。 示例源代码:https://github.com/zhangkaitao/shiro-example; 加qun 231889722 探讨Spring/Shiro技术。
书中可能涵盖如何在Spring Boot、Spring MVC等常见框架中整合Shiro,以及如何解决实际开发中遇到的问题,比如跨域问题、单点登录等。 总的来说,《跟我一起学Shiro——张开涛》这本书是学习Shiro的宝贵资料,不仅...
简单了解shiro流程原理和使用,对项目中的使用指导还是很有意义的
Shiro框架在高版本中更换了加密算法,从AES-CBC换成了AES-GCM,这导致了之前的exp不能用于新版Shiro的加密解密调用。 在高版本Shiro中,AesCipherService类使用AES-GCM模式进行加密,设置了加密模式为GCM, Padding...
Apache Shiro 是一个强大且易用的 Java 安全框架,提供了认证、授权、加密和会话管理功能,可以非常方便地开发出足够安全的应用。...阅读 "[资料][Java]跟我学Shiro教程.pdf",你将得到更详细的步骤指导和实践案例。
通过《跟我学Shiro》.pdf,你将学习到如何创建 Realm 实现数据源连接、配置 Shiro 安全框架、处理登录和登出逻辑、实现权限控制以及在实际项目中部署和调优 Shiro。 10. **最佳实践** 学习 Shiro 的过程中,了解...
- **背景**:Apache Shiro 是一个强大且易于使用的 Java 安全框架,为开发者提供了一站式的安全解决方案,涵盖了认证、授权、加密以及会话管理等多个方面。 - **特性**: - **易用性**:相比其他复杂的安全框架,...
"跟我学Shiro教程"资源包包含了全面学习Shiro所需的重要材料,包括文档和实践示例。 首先,我们来看《Apache_Shiro参考手册中文版.pdf》。这本书籍详细介绍了Shiro框架的各个组件和使用方法。通过阅读,你可以了解...
"跟我学Shiro教程"这个资源显然是为了帮助学习者深入理解并掌握Shiro的核心概念和实际应用。 在Shiro的认证服务中,其主要目标是确认用户身份。这通常涉及用户登录过程,其中用户提供的凭证(如用户名和密码)被...
《跟我学Shiro-java开发+spring开发》是一个深入学习Java安全框架Shiro和Spring集成的教程,旨在帮助开发者掌握这两个关键技术在实际项目中的应用。Shiro是一个强大的且易用的Java安全框架,提供了认证、授权、加密...
在《跟我学Shiro》的第十七章中,作者开涛介绍了如何集成OAuth2,使用Apache Oltu作为OAuth2服务端的实现。实现中涉及以下关键部分: 1. **依赖**:引入了`authzserver`(授权服务器依赖)和`resourceserver`(资源...
Apache Shiro是一个强大易用的Java安全框架,...我找了一版 跟我学Shiro教程PDF,里面讲的很详细.里面还附带了每个章节的源码.值得你收藏哟!饮水思源——原文出自:http://jinnianshilongnian.iteye.com/blog/2049092
《跟我学Shiro》PDF完结版下载, Apache Shiro是Java的一个安全框架。目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Security做的功能强大,但是在实际工作时可能并不...
Apache Shiro 是 Java 的一个安全框架。目前,使用 Apache Shiro 的人越来越多,因为它相当简单,对比 Sp ring Security,可能没有 Spring Security 做的功能强大,但是在实际工作时可能并不需要那么复杂的东西,所 ...