首先,希望还对 spring-security框架完全不懂的新手 下载下Git源码。 引入到项目中。这个短文就是边看源码边聊的。也会启动下项目验证自己的推想。

一、登陆认证的登陆配置项

<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" default-target-url="/index.ht"
  username-parameter="username" password-parameter="password" login-processing-url="/j_spring_security_check"/>
<logout logout-url="/logout.ht"/>

看到这个配置,其实就大略明白了。 这就像配置了一个control/Servlet, userName 参数名字为 ”name“,password 为”password“

然后校验用户密码,通过就跳转的页面为 index.ht 。


spring-security框架维护了一个过滤器链来提供服务, 而<form-login/> 这个登陆配置项其实创建了一个名为UsernamePasswordAuthenticationFilter的过滤器 。

框架提供的这些过滤器,也包括<custom-filter/>配置的过滤器。都是通过假名有严格顺序来执行的。稍后详细介绍自定义过滤器。

UsernamePasswordAuthenticationFilter :

正如我们配置的这些参数,也会有默认配置的   比如

usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY =“j_username”,

passwordParameter=“j_password”

默认接受form请求地址 :j_spring_security_check ,

这些可配置的参数,都会存在默认参数。这些参数的读取是在 Initializing Spring root WebApplicationContext 后,加载并且解析xml配置文件。然后初始化ioc 容器。形成上面所提的过滤器链。

二、简单说一下解析xml 过程

HttpSecurityBeanDefinitionParser.parse() {  filterChains.add(createFilterChain(element, pc)); }

createFilterChain方法会调用 AuthenticationConfigBuilder的构造方法 初始化各种filter        createFormLoginFilter(sessionStrategy, authenticationManager); 即为登录配置信息xml的解析处理方法:

SecurityNamespaceHandler.parse(Element element, ParserContext pc)  //

关键代码:

String name = pc.getDelegate().getLocalName(element);
BeanDefinitionParser parser = parsers.get(name);
通过配置项的名字。以策略模式获取到专用解析器 都实现自BeanDefinitionParser 接口, 通过父类的引用执行子类的具体实现。调用这些子类的parse()方法eg:RememberMeBeanDefinitionParser,LogoutBeanDefinitionParser等、、

错误代码不必看

<form-login/> 的解析在 FormLoginBeanDefinitionParser,  解析后拿到配置的参数,然后初始化一个filter 。

不知道这个解析方法为啥没有实现BeanDefinitionParser 。 本来不想贴代码的。更想愿意读的人自己下载源码自己看。

三、获取登陆获取账号密码

切面走到这个登陆过滤器的时候   UsernamePasswordAuthenticationFilter.attemptAuthentication()  的方法    会从request中,通过配置的userNameParam ,passwordParam 获取 name password

然后构造一个包装了密码账号的对象: new UsernamePasswordAuthenticationToken(password,username)

然后调用接口 AuthenticationManager.authenticate() (认证管理类中的一个实现类 ProviderManager的认证方法

四、配置验证密码的认证管理类

配置认证管理类 AuthenticationManager 需要 给它提供了一个 user-service  bean    来通过用户名获取用户 

这个userDetailProvider bean 需要实现 UserDetailsService接口 提供一个 loadUserByUsername()方法。

配置项:

<security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="userDetailProvider"/>
</security:authentication-manager>
<bean id="userDetailProvider" class="com.hotent.web.security.provider.UserAuthProvider"/> 

然后 从ProviderManager 中的  List<AuthenticationProvider> providers认证策略都  拿出来 进行认证(虚)

AbstractUserDetailsAuthenticationProvider .authenticate()

retrieveUser() // 调用子类DaoAuthenticationProvider的实现方法

DaoAuthenticationProvider.retrieveUser() 会通过我之前配置的userDetailProvider.loadUserByUsername(username),获取用户,

然后preAuthenticationChecks.check(user);  校验用户是否可用、锁定、过期

然后调用additionalAuthenticationChecks()方法验证密码。

五、配置 密码加密方式

接着我登陆不上才发现没有配置密码的加密类型。随便找了 个文档。配了下、居然发现启动不了,妹的。

还好我比较机智,找到了xsd校验文件

顺利找到了正确配置方法,在authentication-provider    element下、 有一个password-encoder   xs:element

这个element 有个attribute<xs:attributeGroup ref="security:password-encoder.attlist"/>,这个想必就是spring-security所支持的所有加密类型了。那xml 就改成了 这样

最终authenticationManager的配置  如下

<security:authentication-manager alias="authenticationManager"><!-- 鉴定管理类 -->
<security:authentication-provider user-service-ref="userDetailProvider">
<security:password-encoder hash="sha-256"/>
</security:authentication-provider>
</security:authentication-manager>

其实很少有人这么傻着从校验文件 去查属性的。 除了像我这种机智到二的人。 其实官方文档说的很清楚,而且xml也会有提示。但是我抱着探究的态度还是直接看xsd。

这样密码加密校验就通过。

接着将成功登陆用户,和用户信息发布出一个事件

applicationEventPublisher.publishEvent(new AuthenticationSuccessEvent(authentication));

///

六、登陆的扩展

很多时候,我们希望做更多的扩展、比如加一些U盾之类的口令啦、短信校验啦。验证码啦。 那么要实现、可以加些自定义的过滤器,也可以重写一些方法,等等、初次探究,我现在还不够清楚。  不过这些都略有些麻烦。

其实如果你自己去校验用户。然后将用户登录信息放入SecurityContext 里面 也就可以随心所欲了。

如下图   验证账号密码、验证码 的截图略过   !直接是验证密码后的操作。

关键代码  

  UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, encrptPassword);
  authRequest.setDetails(new WebAuthenticationDetails(request));
  SecurityContext securityContext = SecurityContextHolder.getContext();
  Authentication auth = authenticationManager.authenticate(authRequest);
  securityContext.setAuthentication(auth);
  sessionStrategy.onAuthentication(auth, request, response);  

注入要使用的类

  @Resource(name = "authenticationManager")
private AuthenticationManager authenticationManager = null;
@Resource
UserDetailsService userDetailsService;
@Resource
private SessionAuthenticationStrategy sessionStrategy= new NullAuthenticatedSessionStrategy();

注入的authenticationManager 其实就是之前写到的  ProviderManager

我们直接使用用户名,密码(加密后) 构建了UsernamePasswordAuthenticationToken(为存放密码账号信息的一个令牌) 是Authentication接口的一个实例。然后把构建好的  authentication 发送给authenticationManager 进行校验 。

authenticationManager 成功校验后,返回一个完全的 Authentication 实例。

SecurityContextHolder.getContext().setAuthentication(...)

Spring Security 并不知道你怎么把Authentication 对象 放到了SecurityContextHolder 里面,唯一关键点就是 “SecurityContextHolder 已经包含了一个 Authentication 标识了一个主体”。  这样就能满足AbstractSecurityInterceptor 之前的验证一个用户需要。

所以、这个authentication放入SecurityContextHolder的过程可以有很多种方式、一个过滤器、一个control方法、就能达到目的,自然就实现了登陆。

有空继续

spring-security 登陆认证之初次探究的更多相关文章

  1. 最简单易懂的Spring Security 身份认证流程讲解

    最简单易懂的Spring Security 身份认证流程讲解 导言 相信大伙对Spring Security这个框架又爱又恨,爱它的强大,恨它的繁琐,其实这是一个误区,Spring Security确 ...

  2. Spring Cloud实战 | 第九篇:Spring Cloud整合Spring Security OAuth2认证服务器统一认证自定义异常处理

    本文完整代码下载点击 一. 前言 相信了解过我或者看过我之前的系列文章应该多少知道点我写这些文章包括创建 有来商城youlai-mall 这个项目的目的,想给那些真的想提升自己或者迷茫的人(包括自己- ...

  3. Spring Security 接口认证鉴权入门实践指南

    目录 前言 SpringBoot 示例 SpringBoot pom.xml SpringBoot application.yml SpringBoot IndexController SpringB ...

  4. SpringBoot Spring Security 核心组件 认证流程 用户权限信息获取详细讲解

    前言 Spring Security 是一个安全框架, 可以简单地认为 Spring Security 是放在用户和 Spring 应用之间的一个安全屏障, 每一个 web 请求都先要经过 Sprin ...

  5. 学习Spring Boot:(二十八)Spring Security 权限认证

    前言 主要实现 Spring Security 的安全认证,结合 RESTful API 的风格,使用无状态的环境. 主要实现是通过请求的 URL ,通过过滤器来做不同的授权策略操作,为该请求提供某个 ...

  6. Spring Security登陆

    本文参考或摘录自:http://haohaoxuexi.iteye.com/blog/2154714 在上一篇中使用Spring Security做了一些安全控制,如Spring Security 自 ...

  7. 学习Spring Security OAuth认证(一)-授权码模式

    一.环境 spring boot+spring security+idea+maven+mybatis 主要是spring security 二.依赖 <dependency> <g ...

  8. Spring Security 安全认证

    Spring Boot 使用 Mybatis 依赖 <dependency> <groupId>org.mybatis.spring.boot</groupId> ...

  9. Spring Security 入门(1-5)Spring Security - 匿名认证

    匿名认证 对于匿名访问的用户,Spring Security 支持为其建立一个匿名的 AnonymousAuthenticationToken 存放在 SecurityContextHolder 中, ...

随机推荐

  1. javascript之闭包深入理解(一)

    曾经在开始学习javascript的时候,很是不理解闭包的概念.今天想对它详细的剖析. 在说清楚闭包之前,必须先清楚作用域链. 作用域链 我们知道,执行环境是js中最为重要的一个概念.执行环境定义了变 ...

  2. java Socket 长连接 心跳包 客户端 信息收发 demo

    今天写了个socket的测试小程序,代码如下 import java.io.IOException; import java.io.InputStream; import java.io.Output ...

  3. PHPCMS v9 在windows2008系统 IIS7 下设置伪静态的方法

    安装环境:windows2008+IIS7.0+PHP5+MYSQL5 一.安装phpcms v9程序,设置伪静态.如图: 二.安装IIS7官方Url重写模块 1.先到IIS官方下载模块 下载地址:h ...

  4. centos6.4虚拟机vmware-tools安装及启动到进度条卡死

    vmware-tools安装: linux-VMware tools安装步骤: (1)在CD-ROM虚拟光驱中选择使用ISO镜像,找到VMWARE TOOLS 安装文件,如D:\VMware\VMwa ...

  5. UIApplication-备用

    iPhone应用程序是由主函数main启动,它负责调用UIApplicationMain函数,该函数的形式如下所示: int UIApplicationMain ( int argc, char *a ...

  6. Decimal Basic 学习笔记(1)

    定义变量 LET a 输入变量值 INPUT a INPUT a,b 运算结果绝对值小于1前面的0省略,科学计数 PRINT语句 数值直接写,字符串用“” 通过 分号: 和 逗号,来分隔显示两个项目 ...

  7. 我只能说,CDH5真的屌爆了!!!

    参考URL http://blog.csdn.net/yangzhaohui168/article/details/34185579 http://blog.csdn.net/yangzhaohui1 ...

  8. 交叉编译环境以及开发板上-/bin/sh: ./hello: not found(使用arm-linux-gcc -static -o 来进行静态编译)

    目标板是S3C2440.至于交叉编译环境的搭建就不多说了,网上很多教程. 搭建好了交叉编译环境后,第一件事就是传说中的”Hello,World!”. 一. 主机编译环节 我使用的系统是ubuntu10 ...

  9. ASCII、Unicode、GBK和UTF-8字符编码的区别联系[转]

    http://dengo.org/archives/901 这是我看过的最好的一篇讲述编码的文章 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到 ...

  10. SolrCloud 5.2.1 installation and configuration

    虽然不是很有技术含量的事情,主要依靠的是阅读能力,然而知识的东西还是记录一下,以备后继待查. 环境相关 1. Server:h1,h2,h3 2. OS RHEL 6.2 3. Zookeeper 3 ...