博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring Boot Shiro权限管理--自定义 FormAuthenticationFilter验证码整合
阅读量:4944 次
发布时间:2019-06-11

本文共 7962 字,大约阅读时间需要 26 分钟。

思路

shiro使用FormAuthenticationFilter进行表单认证,验证校验的功能应该加在FormAuthenticationFilter中,在认证之前进行验证码校验。
需要写FormAuthenticationFilter的子类,继承FormAuthenticationFilter,改写它的认证方法,在认证之前进行验证码校验。

自定义FormAuthenticationFilter

package com.example.config.shiro;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;public class CustomFormAuthenticationFilter extends FormAuthenticationFilter{    @Override      protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {          // 在这里进行验证码的校验          HttpServletRequest httpServletRequest = (HttpServletRequest) request;          HttpSession session = httpServletRequest.getSession();            // 取出验证码          String validateCode = (String) session.getAttribute("validateCode");          // 取出页面的验证码          // 输入的验证和session中的验证进行对比          String randomcode = httpServletRequest.getParameter("randomcode");          if (randomcode != null && validateCode != null && !randomcode.equals(validateCode)) {              // 如果校验失败,将验证码错误失败信息,通过shiroLoginFailure设置到request中              httpServletRequest.setAttribute("shiroLoginFailure", "kaptchaValidateFailed");//自定义登录异常              // 拒绝访问,不再校验账号和密码              return true;          }          return super.onAccessDenied(request, response);      }  }

在ShiroConfiguration.java中的shiroFilter方法注入自定义FormAuthenticationFilter

@Bean    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {        System.out.println("ShiroConfiguration.shiroFilter()");        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();                Map
filters = shiroFilterFactoryBean.getFilters();//获取filters filters.put("authc", new CustomFormAuthenticationFilter());//将自定义 的FormAuthenticationFilter注入shiroFilter中 // 必须设置SecuritManager shiroFilterFactoryBean.setSecurityManager(securityManager); // 拦截器 Map
filterChainDefinitionMap = new LinkedHashMap
(); // 配置退出过滤器,其中的具体代码Shiro已经替我们实现了 filterChainDefinitionMap.put("/logout", "logout"); //验证码可以匿名访问 filterChainDefinitionMap.put("/validatecodeServlet", "anon"); //配置记住我或认证通过可以访问的地址 filterChainDefinitionMap.put("/index", "user"); filterChainDefinitionMap.put("/", "user"); //
:这是一个坑呢,一不小心代码就不好使了; //
filterChainDefinitionMap.put("/**", "authc"); // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面 shiroFilterFactoryBean.setLoginUrl("/login"); // 登录成功后要跳转的链接 shiroFilterFactoryBean.setSuccessUrl("/index"); // 未授权界面; shiroFilterFactoryBean.setUnauthorizedUrl("/403"); shiroFilterFactoryBean .setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; }

ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();//获取filters
filters.put("authc", new CustomFormAuthenticationFilter());//将自定义 的FormAuthenticationFilter注入shiroFilter中  

 登录方法加入自定义的异常kaptchaValidateFailed

@RequestMapping(value = "/login", method = RequestMethod.POST)      public String login(HttpServletRequest request, Map
map) { System.out.println("HomeController.login"); // 登录失败从request中获取shiro处理的异常信息 // shiroLoginFailure:就是shiro异常类的全类名 String exception = (String) request.getAttribute("shiroLoginFailure"); String msg = ""; if (exception != null) { if (UnknownAccountException.class.getName().equals(exception)) { System.out.println("UnknownAccountException -->帐号不存在:"); msg = "UnknownAccountException -->帐号不存在:"; } else if (IncorrectCredentialsException.class.getName().equals(exception)) { System.out.println("IncorrectCredentialsException -- > 密码不正确:"); msg = "IncorrectCredentialsException -- > 密码不正确:"; } else if ("kaptchaValidateFailed".equals(exception)) { System.out.println("kaptchaValidateFailed -- > 验证码错误"); msg = "kaptchaValidateFailed -- > 验证码错误"; } else { msg = "else >> " + exception; System.out.println("else -- >" + exception); } } map.put("msg", msg); // 此方法不处理登录成功,由shiro进行处理. return "/login"; }

login.html

    
Insert title here 错误信息:

账号:

密码:

验证码:

记住我

验证码Servlet

package com.example.servlet;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.io.IOException;import java.io.OutputStream;import java.util.Random;import javax.imageio.ImageIO;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;@WebServlet(urlPatterns="/validatecodeServlet")public class ValidatecodeServlet extends HttpServlet{     /**     *      */    private static final long serialVersionUID = 1L;    @Override          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {              System.out.println(">>>>>>>>>>doGet()<<<<<<<<<<<");              doPost(req, resp);          }                @Override          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {              System.out.println(">>>>>>>>>>doPost()<<<<<<<<<<<");              int width = 60;            int height = 32;            //create the image            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);            Graphics g = image.getGraphics();            // set the background color            g.setColor(new Color(0xDCDCDC));            g.fillRect(0, 0, width, height);            // draw the border            g.setColor(Color.black);            g.drawRect(0, 0, width - 1, height - 1);            // create a random instance to generate the codes            Random rdm = new Random();            String hash1 = Integer.toHexString(rdm.nextInt());            System.out.print(hash1);            // make some confusion            for (int i = 0; i < 50; i++) {                int x = rdm.nextInt(width);                int y = rdm.nextInt(height);                g.drawOval(x, y, 0, 0);            }            // generate a random code            String capstr = hash1.substring(0, 4);            HttpSession session = req.getSession(true);            //将生成的验证码存入session            session.setAttribute("validateCode", capstr);            g.setColor(new Color(0, 100, 0));            g.setFont(new Font("Candara", Font.BOLD, 24));            g.drawString(capstr, 8, 24);            g.dispose();            //输出图片            resp.setContentType("image/jpeg");            OutputStream strm = resp.getOutputStream();            ImageIO.write(image, "jpeg", strm);            strm.close();                      }  }

Application.java

package com.example;    import org.springframework.boot.SpringApplication;  import org.springframework.boot.autoconfigure.SpringBootApplication;  import org.springframework.boot.web.servlet.ServletComponentScan;@ServletComponentScan @SpringBootApplication  public class Application {       public static void main(String[] args) {          SpringApplication.run(Application.class, args);      }  }

 

 

转载于:https://www.cnblogs.com/but009/p/7568007.html

你可能感兴趣的文章
实验十 指针2
查看>>
常见HTTP状态码
查看>>
vim 空格和换行的删除和替换
查看>>
ionic 入门学习
查看>>
[python]pickle和cPickle
查看>>
末日了,天是灰色的。
查看>>
Vuejs vm对象详解
查看>>
自定义RatingBar的一个问题(只显示显示一个星星)
查看>>
剑指Offer--二叉树的镜像
查看>>
PAT-BASIC-1031-查验身份证
查看>>
Python笔记5----集合set
查看>>
连连看小游戏
查看>>
(180905)如何通过梯度下降法降低损失----Google机器学习速成课程笔记
查看>>
面试介绍项目经验(转)
查看>>
<metro>Google的验证
查看>>
Oracle 表的分组操作
查看>>
在OS X上的Intllij Idea中配置GlassFish
查看>>
用查表法快速转换yv12到RGB【转】
查看>>
使用公钥登录SSL
查看>>
hdu 1290_献给杭电五十周年校庆的礼物
查看>>