2017/06/14这一天,是我玩Shiro安全框架最刻骨铭心的一天。由于Shiro今天给我深深的补了一刀,在这儿我也给各位补一刀吧,其实问题很简单,解决方式也极其简单,只是给各位分享一下这个错误,纯属给各位长点经验值。css
以前本身搭建了一套系统拿来练手,将Shiro请到这套系统中做为了第一道防锁线,今天闲来无事想加个短信验证码上去,就登录了中国建网,还好,以前玩剩下的还有3条短信,因而就小忙了起来,找到好久之前玩过的SMS短信发送的那段代码,可是代码很乱很脏,由于那时候不懂事儿瞎写的,如今整理了一下我就不客气了,给你们贴在这儿了,哈哈~~因为这是一段模版代码,只需把本身在短信平台注册的用户名和接口调用的秘匙补上去,还有将你想要发送的随机验证码和短信模板内容告诉接口就OK。前端
1 public static String sendCode(String url,String encoded,String mobile,String SMSTemplate){ 2 //获取随机6位验证码
3 String code = VerifyCodeUtils.generateVerifyCode(6); 4 HttpClient client = new HttpClient(); 5 PostMethod post = new PostMethod(url); 6 post.addRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset="+encoded); 7 NameValuePair[] data = { 8 new NameValuePair("Uid", 用户名), 9 new NameValuePair("Key", 秘匙), 10 new NameValuePair("smsMob", mobile), 11 new NameValuePair("smsText", "验证码:"+code+SMSTemplate)}; 12 post.setRequestBody(data); 13 try { 14 client.executeMethod(post); 15 Header[] headers = post.getResponseHeaders(); 16 int statusCode = post.getStatusCode(); 17 System.out.println("statusCode:" + statusCode); 18 for (Header h : headers) { 19 System.out.println(h.toString()); 20 } 21 String result = new String(post.getResponseBodyAsString().getBytes("gbk")); 22 System.out.println(result); // 打印返回消息状态
23
24 post.releaseConnection(); 25 } catch (Exception e) { 26 e.printStackTrace(); 27 } 28
29 return code; 30 }
需求:用户登陆要求必须输入正确的用户名和密码,最后还要二次验证经过,发送短信验证码来校验该用户是否合法?ajax
需求分析及场景还原:spring
因为个人登陆功能是经过shiro安全框架来实现的,因此短信验证码功能就必须经过发送ajax异步请求后台,将系统发送出去的短信验证码保存在了session中,而后在用户认证过程当中取出登陆用户在页面输入的验证码对比便可。可是,不幸的是,我不够老道不够细心经验不足,致使shiro让我围着它转了将近一天。点击按钮获取短信验证码,在这儿我是经过给按钮绑定点击事件来发送ajax请求,后台经过调用上面抽取的工具方法来给指定用户发送短信内容,逻辑没错吧。就这么简单,为何我就能玩出302 Found呢,也许你们还不清楚302 Found是什么意思吧?我也不说网上那些绕来绕去的说法,个人理解就是资源存在,可是因为重定向设定权限而致使未正确跳转至目标连接。找了一天资料,学了各类说法,也试了各类方法,可是最后解决问题的是一句出乎意料的简单配置,下面就给你们把现场布置一下吧,302 Found的奇妙出现,我居然分析了那么久。浏览器
大家不要怀疑我后台代码写错了或是前端代码写错了,没有的事儿。当我一点击按钮ajax方法不执行,在浏览器中打断点各类尝试走到发送ajax的那段代码就跳过去,请求也不发,后台代码确定也不执行,为啥,难道我前端js代码写错了?不会啊,昨天还刚把异步加载菜单的那玩意儿给搞出来了,js代码写了一成天也没出什么意外,今天就写这么几行简单的js代码不会太过度吧。因而就各类打断点各类分析,我这我的吧,在开发中只要是我代码的执行逻辑没问题,我就会把他测试到烂也得把问题找出来,行此次我输,实在是耗不起啊,也不是太大的问题,就这么耗着不值得。叫师兄过来看看吧,也许当局者迷,他过来也是一顿断点各类走流程,没错啊你这咋回事啊,奇了怪了~~~我看他也被这看似正常内藏大坑的代码搞无语了,我就说行吧,我再自个儿琢磨一下吧,你先把你的活干了。安全
接着我又趴在桌子上想啊想啊,登陆能正常调用,我发送个ajax不至于这么绝吧,一杯水下肚,巧了,Shiro在跟我开玩笑呢,你利用了我,就得时刻注意个人一举一动,原来我是把发送短信验证码的方法给拦截了,哎吆我滴孩啊,这种错误不是技术惹的祸,而是你就踩过这坑没,只要你玩过这功能玩过这样的业务,你就会,其实我才在IT界混了短短2年多,哪有那么深的手法啊,在这里我不是绕圈子给你们炫我作的功能,而是想给你们分享这种错误,我但愿读到这篇博文的朋友有个印象,之后遇到足够你装了,瞬间解决问题,我们这行不就是拿经验混饭吃嘛。session
解决方式:配置忽略项。在spring管理Shiro安全框架的配置文件中配置获取验证码的方法,让它能够匿名访问便可,就是用户没有登陆,也能够发送请求到后台执行方法。app
1 <!-- shiro链接约束配置 -->
2 <property name="filterChainDefinitions">
3 <value>
4 <!-- 对静态资源设置容许匿名访问 -->
5 /images/** = anon 6 /js/** = anon 7 /css/** = anon 8 <!-- 可匿名访问路径,例如:短信验证码、登陆链接、退出链接等 -->
9 /auth/login = anon 10 /user/sendCode = anon 11 <!-- 剩余其余路径,必须认证经过才能够访问 -->
12 /** = authc 13 </value>
14 </property>
最后提醒你们,之后用到安全框架,就请善待它,这种错误你是学不到的,只有下过坑才能尝到那种美味。框架