文档章节

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

hanzhankang
 hanzhankang
发布于 2014/06/05 18:41
字数 1462
阅读 715
收藏 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

粉丝 159
博文 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

没有更多内容

加载失败,请刷新页面

加载更多

Android WebView制作简易浏览器

最终效果 先创建一个WebView控件,其他的就是通过线性布局在上方加入网址输入框和两个按钮 <WebView android:id="@+id/act_webview_wv" android:layout_width="ma...

lanyu96
9分钟前
0
0
解决MacOS升级系统Sierra到Mojave后git报错

错误信息 升级MacOS Sierra到Mac Mojave后执行git命令报错: xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/......

阿dai
10分钟前
0
0
兄弟连区块链教程以太源码分析CMD深入分析(一)

cmd包分析 cmd下面总共有13个子包,除了util包之外,每个子包都有一个主函数,每个主函数的init方法中都定义了该主函数支持的命令,如 geth包下面的: func init() { // Initialize the...

兄弟连区块链入门教程
11分钟前
0
0
Titan Framework MongoDB深入理解1

在TitanFrameWork框架中,已经集成了MongoDB的各个功能,现在我们对框架内部的一些重要类进行分析与解读。 MongoDBConverter 在Titan框架中,比较重要的一个接口就是MongoDBConverter,它是作...

云季科技
17分钟前
0
0
SpringBoot集成Quartz

SpringBoot集成Quartz 什么是Quartz Quartz is a richly featured, open source job scheduling library that can be integrated within virtually any Java application - from the smalle......

Grittan
21分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部