Spring源代码解析(九):Spring Acegi框架鉴权的实现
2010-02-24 19:22
399 查看
publicvoid doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//这里检验是不是符合ServletRequest/SevletResponse的要求
if (!(request instanceof HttpServletRequest)) {
throw new ServletException("Can only process HttpServletRequest");
}
if (!(response instanceof HttpServletResponse)) {
throw new ServletException("Can only process HttpServletResponse");
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
//根据HttpServletRequest和HttpServletResponse来进行验证
if (requiresAuthentication(httpRequest, httpResponse)) {
if (logger.isDebugEnabled()) {
logger.debug("Request is to process authentication");
}
//这里定义Acegi中的Authentication对象来持有相关的用户验证信息
Authentication authResult;
try {
onPreAuthentication(httpRequest, httpResponse);
//这里的具体验证过程委托给子类完成,比如AuthenticationProcessingFilter来完成基于Web页面的用户验证
authResult = attemptAuthentication(httpRequest);
} catch (AuthenticationException failed) {
// Authentication failed
unsuccessfulAuthentication(httpRequest, httpResponse, failed);
return;
}
// Authentication success
if (continueChainBeforeSuccessfulAuthentication) {
chain.doFilter(request, response);
}
//完成验证后的后续工作,比如跳转到相应的页面
successfulAuthentication(httpRequest, httpResponse, authResult);
return;
}
chain.doFilter(request, response);
} public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //这里检验是不是符合ServletRequest/SevletResponse的要求 if (!(request instanceof HttpServletRequest)) { throw new ServletException("Can only process HttpServletRequest"); } if (!(response instanceof HttpServletResponse)) { throw new ServletException("Can only process HttpServletResponse"); } HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; //根据HttpServletRequest和HttpServletResponse来进行验证 if (requiresAuthentication(httpRequest, httpResponse)) { if (logger.isDebugEnabled()) { logger.debug("Request is to process authentication"); } //这里定义Acegi中的Authentication对象来持有相关的用户验证信息 Authentication authResult; try { onPreAuthentication(httpRequest, httpResponse); //这里的具体验证过程委托给子类完成,比如AuthenticationProcessingFilter来完成基于Web页面的用户验证 authResult = attemptAuthentication(httpRequest); } catch (AuthenticationException failed) { // Authentication failed unsuccessfulAuthentication(httpRequest, httpResponse, failed); return; } // Authentication success if (continueChainBeforeSuccessfulAuthentication) { chain.doFilter(request, response); } //完成验证后的后续工作,比如跳转到相应的页面 successfulAuthentication(httpRequest, httpResponse, authResult); return; } chain.doFilter(request, response); }
在AuthenticationProcessingFilter中的具体验证过程是这样的:
Java代码
![](http://www.javaeye.com/images/icon_copy.gif)
public Authentication attemptAuthentication(HttpServletRequest request)
throws AuthenticationException {
//这里从HttpServletRequest中得到用户验证的用户名和密码
String username = obtainUsername(request);
String password = obtainPassword(request);
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
//这里根据得到的用户名和密码去构造一个Authentication对象提供给AuthenticationManager进行验证,里面包含了用户的用户名和密码信息
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Place the last username attempted into HttpSession for views
request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
//这里启动AuthenticationManager进行验证过程
return this.getAuthenticationManager().authenticate(authRequest);
} public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException { //这里从HttpServletRequest中得到用户验证的用户名和密码 String username = obtainUsername(request); String password = obtainPassword(request); if (username == null) { username = ""; } if (password == null) { password = ""; } //这里根据得到的用户名和密码去构造一个Authentication对象提供给AuthenticationManager进行验证,里面包含了用户的用户名和密码信息 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); // Place the last username attempted into HttpSession for views request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username); // Allow subclasses to set the "details" property setDetails(request, authRequest); //这里启动AuthenticationManager进行验证过程 return this.getAuthenticationManager().authenticate(authRequest); }
在Acegi框架中,进行验证管理的主要类是AuthenticationManager,我们看看它是怎样进行验证管理的 - 验证的调用入口是authenticate在AbstractAuthenticationManager的实现中:
//这是进行验证的函数,返回一个Authentication对象来记录验证的结果,其中包含了用户的验证信息,权限配置等,同时这个Authentication会以后被授权模块使用
Java代码
![](http://www.javaeye.com/images/icon_copy.gif)
//如果验证失败,那么在验证过程中会直接抛出异常
public final Authentication authenticate(Authentication authRequest)
throws AuthenticationException {
try {//这里是实际的验证处理,我们下面使用ProviderManager来说明具体的验证过程,传入的参数authRequest里面已经包含了从HttpServletRequest中得到的用户输入的用户名和密码
Authentication authResult = doAuthentication(authRequest);
copyDetails(authRequest, authResult);
return authResult;
} catch (AuthenticationException e) {
e.setAuthentication(authRequest);
throw e;
}
} //如果验证失败,那么在验证过程中会直接抛出异常 public final Authentication authenticate(Authentication authRequest) throws AuthenticationException { try {//这里是实际的验证处理,我们下面使用ProviderManager来说明具体的验证过程,传入的参数authRequest里面已经包含了从HttpServletRequest中得到的用户输入的用户名和密码 Authentication authResult = doAuthentication(authRequest); copyDetails(authRequest, authResult); return authResult; } catch (AuthenticationException e) { e.setAuthentication(authRequest); throw e; } }
在ProviderManager中进行实际的验证工作,假设这里使用数据库来存取用户信息:
Java代码
![](http://www.javaeye.com/images/icon_copy.gif)
public Authentication doAuthentication(Authentication authentication)
throws AuthenticationException {
//这里取得配置好的provider链的迭代器,在配置的时候可以配置多个provider,这里我们配置的是DaoAuthenticationProvider来说明, 它使用数据库来保存用户的用户名和密码信息。
Iterator iter = providers.iterator();
Class toTest = authentication.getClass();
AuthenticationException lastException = null;
while (iter.hasNext()) {
AuthenticationProvider provider = (AuthenticationProvider) iter.next();
if (provider.supports(toTest)) {
logger.debug("Authentication attempt using " + provider.getClass().getName());
//这个result包含了验证中得到的结果信息
Authentication result = null;
try {//这里是provider进行验证处理的过程
result = provider.authenticate(authentication);
sessionController.checkAuthenticationAllowed(result);
} catch (AuthenticationException ae) {
lastException = ae;
result = null;
}
if (result != null) {
sessionController.registerSuccessfulAuthentication(result);
publishEvent(new AuthenticationSuccessEvent(result));
return result;
}
}
}
if (lastException == null) {
lastException = new ProviderNotFoundException(messages.getMessage("ProviderManager.providerNotFound",
new Object[] {toTest.getName()}, "No AuthenticationProvider found for {0}"));
}
// 这里发布事件来通知上下文的监听器
String className = exceptionMappings.getProperty(lastException.getClass().getName());
AbstractAuthenticationEvent event = null;
throws IOException, ServletException {
//这里检验是不是符合ServletRequest/SevletResponse的要求
if (!(request instanceof HttpServletRequest)) {
throw new ServletException("Can only process HttpServletRequest");
}
if (!(response instanceof HttpServletResponse)) {
throw new ServletException("Can only process HttpServletResponse");
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
//根据HttpServletRequest和HttpServletResponse来进行验证
if (requiresAuthentication(httpRequest, httpResponse)) {
if (logger.isDebugEnabled()) {
logger.debug("Request is to process authentication");
}
//这里定义Acegi中的Authentication对象来持有相关的用户验证信息
Authentication authResult;
try {
onPreAuthentication(httpRequest, httpResponse);
//这里的具体验证过程委托给子类完成,比如AuthenticationProcessingFilter来完成基于Web页面的用户验证
authResult = attemptAuthentication(httpRequest);
} catch (AuthenticationException failed) {
// Authentication failed
unsuccessfulAuthentication(httpRequest, httpResponse, failed);
return;
}
// Authentication success
if (continueChainBeforeSuccessfulAuthentication) {
chain.doFilter(request, response);
}
//完成验证后的后续工作,比如跳转到相应的页面
successfulAuthentication(httpRequest, httpResponse, authResult);
return;
}
chain.doFilter(request, response);
} public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //这里检验是不是符合ServletRequest/SevletResponse的要求 if (!(request instanceof HttpServletRequest)) { throw new ServletException("Can only process HttpServletRequest"); } if (!(response instanceof HttpServletResponse)) { throw new ServletException("Can only process HttpServletResponse"); } HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; //根据HttpServletRequest和HttpServletResponse来进行验证 if (requiresAuthentication(httpRequest, httpResponse)) { if (logger.isDebugEnabled()) { logger.debug("Request is to process authentication"); } //这里定义Acegi中的Authentication对象来持有相关的用户验证信息 Authentication authResult; try { onPreAuthentication(httpRequest, httpResponse); //这里的具体验证过程委托给子类完成,比如AuthenticationProcessingFilter来完成基于Web页面的用户验证 authResult = attemptAuthentication(httpRequest); } catch (AuthenticationException failed) { // Authentication failed unsuccessfulAuthentication(httpRequest, httpResponse, failed); return; } // Authentication success if (continueChainBeforeSuccessfulAuthentication) { chain.doFilter(request, response); } //完成验证后的后续工作,比如跳转到相应的页面 successfulAuthentication(httpRequest, httpResponse, authResult); return; } chain.doFilter(request, response); }
在AuthenticationProcessingFilter中的具体验证过程是这样的:
Java代码
![](http://www.javaeye.com/images/icon_copy.gif)
public Authentication attemptAuthentication(HttpServletRequest request)
throws AuthenticationException {
//这里从HttpServletRequest中得到用户验证的用户名和密码
String username = obtainUsername(request);
String password = obtainPassword(request);
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
//这里根据得到的用户名和密码去构造一个Authentication对象提供给AuthenticationManager进行验证,里面包含了用户的用户名和密码信息
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Place the last username attempted into HttpSession for views
request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
//这里启动AuthenticationManager进行验证过程
return this.getAuthenticationManager().authenticate(authRequest);
} public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException { //这里从HttpServletRequest中得到用户验证的用户名和密码 String username = obtainUsername(request); String password = obtainPassword(request); if (username == null) { username = ""; } if (password == null) { password = ""; } //这里根据得到的用户名和密码去构造一个Authentication对象提供给AuthenticationManager进行验证,里面包含了用户的用户名和密码信息 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); // Place the last username attempted into HttpSession for views request.getSession().setAttribute(ACEGI_SECURITY_LAST_USERNAME_KEY, username); // Allow subclasses to set the "details" property setDetails(request, authRequest); //这里启动AuthenticationManager进行验证过程 return this.getAuthenticationManager().authenticate(authRequest); }
在Acegi框架中,进行验证管理的主要类是AuthenticationManager,我们看看它是怎样进行验证管理的 - 验证的调用入口是authenticate在AbstractAuthenticationManager的实现中:
//这是进行验证的函数,返回一个Authentication对象来记录验证的结果,其中包含了用户的验证信息,权限配置等,同时这个Authentication会以后被授权模块使用
Java代码
![](http://www.javaeye.com/images/icon_copy.gif)
//如果验证失败,那么在验证过程中会直接抛出异常
public final Authentication authenticate(Authentication authRequest)
throws AuthenticationException {
try {//这里是实际的验证处理,我们下面使用ProviderManager来说明具体的验证过程,传入的参数authRequest里面已经包含了从HttpServletRequest中得到的用户输入的用户名和密码
Authentication authResult = doAuthentication(authRequest);
copyDetails(authRequest, authResult);
return authResult;
} catch (AuthenticationException e) {
e.setAuthentication(authRequest);
throw e;
}
} //如果验证失败,那么在验证过程中会直接抛出异常 public final Authentication authenticate(Authentication authRequest) throws AuthenticationException { try {//这里是实际的验证处理,我们下面使用ProviderManager来说明具体的验证过程,传入的参数authRequest里面已经包含了从HttpServletRequest中得到的用户输入的用户名和密码 Authentication authResult = doAuthentication(authRequest); copyDetails(authRequest, authResult); return authResult; } catch (AuthenticationException e) { e.setAuthentication(authRequest); throw e; } }
在ProviderManager中进行实际的验证工作,假设这里使用数据库来存取用户信息:
Java代码
![](http://www.javaeye.com/images/icon_copy.gif)
public Authentication doAuthentication(Authentication authentication)
throws AuthenticationException {
//这里取得配置好的provider链的迭代器,在配置的时候可以配置多个provider,这里我们配置的是DaoAuthenticationProvider来说明, 它使用数据库来保存用户的用户名和密码信息。
Iterator iter = providers.iterator();
Class toTest = authentication.getClass();
AuthenticationException lastException = null;
while (iter.hasNext()) {
AuthenticationProvider provider = (AuthenticationProvider) iter.next();
if (provider.supports(toTest)) {
logger.debug("Authentication attempt using " + provider.getClass().getName());
//这个result包含了验证中得到的结果信息
Authentication result = null;
try {//这里是provider进行验证处理的过程
result = provider.authenticate(authentication);
sessionController.checkAuthenticationAllowed(result);
} catch (AuthenticationException ae) {
lastException = ae;
result = null;
}
if (result != null) {
sessionController.registerSuccessfulAuthentication(result);
publishEvent(new AuthenticationSuccessEvent(result));
return result;
}
}
}
if (lastException == null) {
lastException = new ProviderNotFoundException(messages.getMessage("ProviderManager.providerNotFound",
new Object[] {toTest.getName()}, "No AuthenticationProvider found for {0}"));
}
// 这里发布事件来通知上下文的监听器
String className = exceptionMappings.getProperty(lastException.getClass().getName());
AbstractAuthenticationEvent event = null;
相关文章推荐
- Spring源代码解析(九):Spring Acegi框架鉴权的实现
- Spring源代码解析(九):Spring Acegi框架鉴权的实现
- Spring源代码解析(十):Spring Acegi框架授权的实现
- Spring源代码解析(九):Spring Acegi框架鉴权的实现
- Spring源代码解析(十):Spring Acegi框架授权的实现
- Spring源代码解析(十):Spring Acegi框架授权的实现
- Spring Acegi框架鉴权的实现
- Spring Acegi框架授权的实现
- Spring源代码解析(八):Spring驱动Hibernate的实现
- spring中注解处理框架解析----源代码实现
- java计划任务调度框架quartz结合spring实现调度的配置实例代码分享
- 转:Spring技术内幕——深入解析Spring架构与设计原理(三)IOC实现原理
- 在Spring Boot框架下使用WebSocket实现聊天功能
- Android滑动菜单框架完全解析,教你如何一分钟实现滑动菜单特效
- (3)spring boot如何使用第三方json解析框架
- 微服务框架Spring Cloud介绍 Part1: 使用事件和消息队列实现分布式事务
- Jimoshi_Spring 框架学习(一)--Spring实现IOC思想、javabean对象、Spring对象和对象之间关系
- 黑马程序员 实现类似spring的可配置的AOP框架
- Spring源码解析-容器的基本实现
- spring整合shiro框架的实现步骤记录