Jeesite Login 登录 分析
来源:互联网 发布:python list太大拆分 编辑:程序博客网 时间:2024/06/09 15:00
1.sysLogin.jsp
本文采用从前端到后台的形式,整体的阐述一下jeesite中login模块的交互流程,整个jeesite的重要功能我拟将他分为login,list,权限三个部分,应该包括了我们需要实现的大部分功能,计划将这三个部分逐一写出。
jsp这部分我并不太熟,详见嘉炜的jsp讲解,我这里只挑出重要部分介绍:
<form id="loginForm" class="form login-form" action="${ctx}/login" method="post">
整个jsp页面其实就是一个表单,它的主要目的就是接受用户输入的用户名和密码字段,然后交给后台处理。action变量指定了该表达的提交方式,既是交由/a/login所对应的函数来处理。
<input type="text" id="username" name="username" class="required" value="https://my.oschina.net/u/2601842/blog/${username}" placeholder="登录名"><input type="password" id="password" name="password" class="required" placeholder="密码"/>
以上就是表单里的两个属性,一个属性名为username,一个名为password,表单会借由request属性传到函数当中,届时就能通过getUsername和getPassword两个函数从request中取出。这部分是在FormAuthenticationFilter中的createToken函数中实现,下文中会详细介绍。
Login模块中的jsp非常简单,难点主要在于shiro的应用上,这也是该模块与普通list模块的区别之处。
2.shiro
之前已经写过一篇shiro相关的文章,只是之前的shiro文章是作为简单的shiro教程来写的,内容大而全,所以知识点之间的串联难免会差一些,这次只做为jeesite应用来写,更注重在逻辑方面,若有问题可以参考前一篇文章。
其实这里也设计到一些spring-mvc的内容,不过之前也已经写过了,而且也很简单,就不作为单独的一章了。
上回合说到,jsp将username和password打包扔给后台,那么后台是由什么接受呢?在spring-mvc中,负责接受前台数据的是controller部分,而form中所指定的action是/a/login。
@RequestMapping(value = "https://my.oschina.net/u/2601842/blog/${adminPath}/login", method = RequestMethod.GET)public String login(HttpServletRequest request, HttpServletResponse response, Model model) { User user = UserUtils.getUser(); // 如果已经登录,则跳转到管理首页 if(user.getId() != null){ return "redirect:"+Global.getAdminPath(); } return "modules/sys/sysLogin";} @RequestMapping(value = "https://my.oschina.net/u/2601842/blog/${adminPath}/login", method = RequestMethod.POST)public String login(@RequestParam(FormAuthenticationFilter.DEFAULT_USERNAME_PARAM) String username, HttpServletRequest request, HttpServletResponse response, Model model) { User user = UserUtils.getUser(); // 如果已经登录,则跳转到管理首页 if(user.getId() != null){ return "redirect:"+Global.getAdminPath(); } model.addAttribute(FormAuthenticationFilter.DEFAULT_USERNAME_PARAM, username); model.addAttribute("isValidateCodeLogin", isValidateCodeLogin(username, true, false)); return "modules/sys/sysLogin";}
很容易就能定位到,以上两个函数就是处理form的函数,或者说正常情况下是由这两个函数来处理。但是仔细看这两个函数,并没有进行逻辑处理,只是简单的检查和跳转。这是因为shiro的登陆功能在controller之前加入了一个filter。这个filter被配置在文件spring-context-shiro.xml文件里。
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <property name="loginUrl" value="https://my.oschina.net/u/2601842/blog/${adminPath}/login" /> <property name="successUrl" value="https://my.oschina.net/u/2601842/blog/${adminPath}" /> <property name="filters"> <map> <entry key="authc" value-ref="formAuthenticationFilter"/> </map> </property> <property name="filterChainDefinitions"> <value> /static/** = anon /userfiles/** = anon ${adminPath}/login = authc ${adminPath}/logout = logout ${adminPath}/** = user </value> </property></bean>
以上就是配置过程最关键的部分。loginuUrl属性所指定的url表示的是所有未通过验证的url所访问的位置,此处就是登录界面;successUrl表示的是成功登陆的url访问的位置,此处就是主页。filters则是配置具体验证方法的位置。在此处,${adminPath}/login = authc指定了/a/login,既登陆页面,所需要的验证权限名为authc,又配置了authc所用的filter为formAuthenticationFilter。
因此整个逻辑是:如果任何地方未登陆,则访问/a/login页面,而/a/login页面的验证权限中又指定了formAuthenticationFilter做为过滤,如果过滤中验证成功,则访问/a这个主页。所以,login.jsp中的表单信息则首先交由formAuthenticationFilter首先处理。
再来看formAuthenticationFilter中的处理,需要关注的类主要在com.thinkgem.jeesite.modules.sys.security这个包里。通常FormAuthenticationFilter是主要逻辑管理类,systemAuthorizingRealm这个类则是数据处理类,相当于DAO。但是直接从代码里没发看出功能,这是因为jeesite中的这两个类都是继承于shiro的类,有很多逻辑并没有在jeesite中实现,所以我并不能贴出全部代码,某些地方只用语言来描述。
大致来讲,首先表单的request被formAuthenticationFilter接收到,然后传给createToken函数,该函数从request中取出name和password,然后生成自定义的一个token传给SystemAuthorizingRealm中的doGetAuthenticationInfo验证。SystemAuthorizingRealm中有systemService的实例,该实例含有userDAO能取出数据库中的name和password。接着由这两个密码生成SimpleAuthenticationInfo,再由info中的逻辑来验证。以上过程中jeesite实现的代码分别如下:
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) { String username = getUsername(request); String password = getPassword(request); if (password==null){ password = ""; } boolean rememberMe = isRememberMe(request); String host = getHost(request); String captcha = getCaptcha(request); return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha);}
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authcToken; if (LoginController.isValidateCodeLogin(token.getUsername(), false, false)){ // 判断验证码 Session session = SecurityUtils.getSubject().getSession(); String code = (String)session.getAttribute(ValidateCodeServlet.VALIDATE_CODE); if (token.getCaptcha() == null || !token.getCaptcha().toUpperCase().equals(code)){ throw new CaptchaException("验证码错误."); } } User user = getSystemService().getUserByLoginName(token.getUsername()); if (user != null) { byte[] salt = Encodes.decodeHex(user.getPassword().substring(0,16)); return new SimpleAuthenticationInfo(new Principal(user), user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName()); } else { return null; }}
- Jeesite Login 登录 分析
- jeesite整合单点登录
- 登录login
- Login登录
- jeesite框架分析
- jeesite框架分析理解
- JEESITE登录流程简单梳理
- JEESITE登录流程简单梳理
- JEESITE登录流程简单梳理
- 登录页面(login)
- urllib2 登录 login
- Selenium login 模拟登录
- easyui 登录页login
- 过滤Login自动登录
- cas 单点登录修改认证方式 jeesite
- cas 单点登录修改认证方式 jeesite
- cas 单点登录修改认证方式 jeesite
- JeeSite
- 【上级笔试之一】数据输入
- Android 手机号中间四位为* 和只取后四位
- 基于python超简洁的顺时针打印矩阵
- GitHub for Windows 安装异常解决办法
- openssl_aes
- Jeesite Login 登录 分析
- 成为专业程序员路上用到的各种优秀资料、神器及框架
- 常用ansible命令
- alpha测试和betal测试
- 推荐系统基础知识
- webpack入门必知必会
- 设计模式之职责链(Chain Of Responsibility)
- spring 定时任务
- 缓存和动态SQL