文档章节

ki4so 登录认证及凭证源码分析

hanzhankang
 hanzhankang
发布于 2014/06/05 18:41
字数 1462
阅读 712
收藏 0

此次以一个单次请求为开始,只研究服务器端对登录的处理过程,并未涉及客户端Server的处理过程。分析得比较啰嗦和杂乱,还请见谅。

Action 请求处理类:

@Controller

com.github.ebnew.ki4so.web.action.LoginAction 类定义:

@Controller

public class LoginAction {

 @Autowired

 protected CredentialResolver credentialResolver;

 @Autowired

 protected Ki4soService ki4soService;

 @Autowired

 protected LoginResultToView loginResultToView;

 /**

  * 登录接口,该接口处理所有与登录有关的请求。 包括以下几种情况: 1.

  * @param  model

  * @return

  */

 @RequestMapping("/login")

 public ModelAndView login(HttpServletRequest request,

   HttpServletResponse response) {

  ModelAndView mv = new ModelAndView("login");

  // 解析用户凭据。

  Credential credential = credentialResolver.resolveCredential(request);

  // 没有提供任何认证凭据。

  if (credential == null) {

   // 设置serivce地址到session中。

   String service = request

     .getParameter(WebConstants.SERVICE_PARAM_NAME);

   if (!StringUtils.isEmpty(service)) {

    request.getSession().setAttribute(

      WebConstants.KI4SO_SERVICE_KEY_IN_SESSION, service);

   }

   // 返回到登录页面,索取用户凭据。

   return mv;

  }

  // 提供了用户凭据

  else {

   // 调用核心结果进行凭据认证。

   LoginResult result = ki4soService.login(credential);

   // 将验证结果转换为视图输出结果。

   mv = loginResultToView.loginResultToView(mv, result, request,

     response);

  }

  return mv;

 }

// set method...

}

 spring-beans.xml 注入定义:

<!-- 组合凭据解析器对象 -->

 <bean id="credentialResolver" class="com.github.ebnew.ki4so.web.action.CompositeCredentialResolver">

  <property name="usernamePasswordCredentialResolver">

   <bean class="com.github.ebnew.ki4so.web.action.UsernamePasswordCredentialResolver"></bean>

  </property>

  <property name="encryCredentialResolver">

   <bean class="com.github.ebnew.ki4so.web.action.EncryCredentialResolver"></bean>

  </property>

 </bean>

 <!-- ki4so中心接口服务 -->

 <bean id="ki4soService" class="com.github.ebnew.ki4so.core.service.Ki4soServiceImpl" autowire="byName"></bean>

 <bean id="loginResultToView" class="com.github.ebnew.ki4so.web.action.DefaultLoginResultToView"></bean>

配置分析:

      这是Spring的典型配置注入方式,通过id可以定位到具体的实现类。

LoginAction 的处理流程:


用户调用login.do调用登录请求-->服务器端接受


服务器端接受后的处理:

-->解析用户凭证

  Credential credential = credentialResolver.resolveCredential(request); 

com.github.ebnew.ki4so.web.action.CompositeCredentialResolver 实现类的resolveCredential(request方法:

功能:

首先,从 http请求的cookie中解析出对应的加密后的凭据信息,如果cookie里没有,就从请求参数中获取(获取后,返回此值的加密信息,否则返回Null)

cookie和请求参数的键名:KI4SO_SERVER_EC

加密方式:



继续分析:加密凭证与非加密凭证:

if(request==null){

   return null;

  }

  Credential credential = null;

  if(encryCredentialResolver!=null){

   //先解析加密后的凭据。

   credential = encryCredentialResolver.resolveCredential(request);

  }

  //若返回空,则用原始凭据解析器解析。

  if(null == credential){

   if(usernamePasswordCredentialResolver!=null){

    credential = usernamePasswordCredentialResolver.resolveCredential(request);

   }

  }

………………

右边代码释义:

如果cookie里有值,就返回cookie里的值;如果没有,就从参数里获取,直接返回凭据对象:EncryCredential

cookie的键:"KI4SO_SERVER_EC"

EncryCredential凭据对象:返回的是一个凭据对象,有个构造方法,

EncryCredential实现了Credential的public boolean isOriginal();方法,此方法的解释是:

EncryCredential构建的对象直接是false

加密后的凭据:也就是说是cookie里的值,cookie里的值是经过加密的

encryCredentialResolver注入的类是:com.github.ebnew.ki4so.web.action.EncryCredentialResolver


如果没有加密凭据,就需要处理原始凭据:

usernamePasswordCredentialResolver的注入类:com.github.ebnew.ki4so.web.action.UsernamePasswordCredentialResolver

处理类的功能:从参数中解析出用户的用户名和密码信息(用户名和密码凭据解析器)。

         

此处理很简单,就是获取参数里的值,构造成:UsernamePasswordCredential,但此时,重写的public boolean isOriginal()方法的返回值就是true

==> 扩展及延伸:在这里可以扩展此类,实现“记住我”的功能,也就是设置cookie的超时时间


----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

以上的分析是针对com.github.ebnew.ki4so.web.action.LoginAction 类中的 public ModelAndView login 上半部分 解析用户凭据 的逻辑,如果用户凭证为空,就直接返回到登录界面;现在我们来分析当用户提供了登录凭据的实现流程:

也就是这一部分:

                        

这里代码看起来很简单,我们就来仔细分析分析。查找 ki4soService 的注入实现类,定位到:com.github.ebnew.ki4so.core.service.Ki4soServiceImpl,关于此类的结构见上图。

此类的相关属性的set注入都能在: spring-beans.xml  找到,我们现在先看login方法的实现:

代码中,最重要的是这段代码:
我们来继续看看authenticationManager注入的配置文件和实现类代码:


authenticate() 方法实现:



代码意思:循环调用所有的用户凭证解析器(配置里的),如果支持此用户凭证,调用:
循环处理完了,就判断是否找到了合适的认证处理器、是否认证通过;理想情况下是顺利进行,认证通过后,就继续下面的流程:解析用户凭据,解析用户凭据的注入配置:
代码分析:
authenticationHandlers 的定义:
也就是我们自己的验证模块:自定义查询用户名、密码进行匹配。 这个是Spring的List注入,说明这个list里有2个子类<bean>,2个类的实现与集成关系:


在上图中标注为*的AbstractUsernamePasswordAuthenticationHandler 抽象类中,实现了超类中的boolean supports(Credential credential);方法:




com.github.ebnew.ki4so.core.authentication.handlers.AbstractPreAndPostProcessingAuthenticationHandler 类实现了超类中的:boolean authenticate(Credential credential)  方法:

doAuthertication()的实现:

authenticateUsernamePasswordInternal() 方法是我们JeejenUsernamePasswordAuthenticationHandler里实现的数据库认证逻辑。


在上面的注入信息里都实现了:Principal resolvePrincipal(Credential credential) 方法

1.  com.github.ebnew.ki4so.core.authentication.resolvers.UsernamePasswordCredentialToPrincipalResolver 类的实现:

2.com.github.ebnew.ki4so.core.authentication.resolvers.EncryCredentialToPrincipalResolver类的实现:

通过循环调用所有的用户凭证解析器,看是否有合适的解析器、是否能解析出有效的用户凭证,如果成功了就返回此凭证(【如果是加密的凭证,就解密出来并生成凭证】)并跳出循环。如果一切都顺利的话,就:

authenticationPostHandler 的注入类是:com.github.ebnew.ki4so.core.authentication.DefaultAuthenticationPostHandler,方法postAuthentication(credential, principal)的实现为:

功能就是:构造验证结果对象并返回

至此,验证流程算是进行到一半了,返回了验证结果对象继续走:com.github.ebnew.ki4so.core.service.Ki4soServiceImpl 方法login()的下一个流程:






代码比较浅显易懂,核心也就是通过验证获得验证结果Authentication,如果验证中途出现异常,把异常类的状态code和msgKey封装成LoginResult返回给调用者处理就好了。

作为Action的LoginAction的具体login方法,负责处理登录结果对象LoginResult,做最终的页面呈现。



原文请见:http://note.youdao.com/share/?id=9dc8af987eeb19fa4c2af0bffb35b24a&type=note

© 著作权归作者所有

共有 人打赏支持
hanzhankang

hanzhankang

粉丝 158
博文 220
码字总数 82578
作品 0
海淀
高级程序员
ki4so 使用原始凭证(表单提交)登录成功后的加密和下次请求的解密 源码分析

ki4so是基于cookie的,cookie并不安全:cookie极容易被伪造,也容易被劫持。Ki4so是通过怎样的方式写cookie和鉴别cookie的呢?(目前ki4so并没有处理cookie劫持的功能,我提出的思路是在coo...

hanzhankang
2014/06/05
0
2
ki4so 登录认证及凭证源码分析

此次以一个单次请求为开始,只研究服务器端对登录的处理过程,并未涉及客户端Server的处理过程。分析得比较啰嗦和杂乱,还请见谅。 Action 请求处理类: @Controller com.github.ebnew.ki4so...

hanzhankang
2014/05/28
0
0
单点登录系统--ki4so

ki4so是一个简约、无状态、易扩展、易伸缩的适合于大型互联网web应用场景的单点登录系统,它功能简单,只实现了统一登录和登出,它最大的特色是将用户状态写入到cookie中,最大程度减少了单点...

杨武兵
2013/09/25
15.9K
5
Git@OSC 项目推荐 —— ki4so 单点登录系统

ki4so是一个简约、无状态、易扩展、易伸缩的适合于大型互联网web应用场景的单点登录系统,它功能简单,只实现了统一登录和登出,它最大的特色是将用户状态写入到cookie中,最大程度减少了单点...

oschina
2015/01/03
23
0
杨武兵/ki4so

ki4so #产品发布计划 ##ki4so 2015新年贺岁版本发布计划 产品发布时间: 2015. 1.1 (新年贺岁版) 产品包括的特性: 统一登入 (提升质量,详细测试) 统一登出(后端实现稳定可靠的统一登出...

杨武兵
2014/12/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

OSChina 周日乱弹 —— 种族不同,禁止交往

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @小小编辑:推荐歌曲《苏菲小姐》- 鱼果 《苏菲小姐》- 鱼果 手机党少年们想听歌,请使劲儿戳(这里) @貓夏:下大雨 正是睡觉的好时候 临睡前...

小小编辑
今天
244
6
Python 搭建简单服务器

Python动态服务器网页(需要使用WSGI接口),基本实现步骤如下: 1.等待客户端的链接,服务器会收到一个http协议的请求数据报 2.利用正则表达式对这个请求数据报进行解析(请求方式、提取出文...

代码打碟手
今天
1
0
Confluence 6 删除垃圾内容

属性(profile)垃圾 属性垃圾的定义为,一个垃圾用户在 Confluence 创建了用户,但是这个用户在自己的属性页面中添加了垃圾 URL。 如果你有很多垃圾用户在你的系统中创建了属性,你可以使用...

honeymose
今天
1
0
qduoj~前端~二次开发~打包docker镜像并上传到阿里云容器镜像仓库

上一篇文章https://my.oschina.net/finchxu/blog/1930017记录了怎么在本地修改前端,现在我要把我的修改添加到部署到本地的前端的docker容器中,然后打包这个容器成为一个本地镜像,然后把这...

虚拟世界的懒猫
今天
1
0
UML中 的各种符号含义

Class Notation A class notation consists of three parts: Class Name The name of the class appears in the first partition. Class Attributes Attributes are shown in the second par......

hutaishi
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部