- 浏览: 369334 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
y806839048:
启动activemq我试了,也不行
ActiveMQ5.0实战三:使用Spring发送,消费topic和queue消息 -
y806839048:
是不是要另外启动activemq
ActiveMQ5.0实战三:使用Spring发送,消费topic和queue消息 -
y806839048:
为什么我的两个应用中,不能实现通信
ActiveMQ5.0实战三:使用Spring发送,消费topic和queue消息 -
fengfujie:
[flash=200,200][/flash][tr][th] ...
JMS消息类型模型 -
fengfujie:
...
JMS消息类型模型
Abstract
The ACEGI security framework provides a robust authentication and authorization mechanism for applications that use the Spring Framework. However, web applications that leverage AJAX for inline editing have special requirements when it comes to authentication. This article shows how to configure the ACEGI framework to handle inline AJAX login.
The AJAX Login Problem
AJAX applications often allow users to add and edit data inline by replacing parts of the page with forms. This is done by replacing the contents of a DIV or P element with new XHTML retrieved from the server using an AJAX request. The exact steps to get inline AJAX editing working in your application are outside the scope of this article but there are a ton of resources available out on the web to help you get started. This article focuses on the what happens when a user’s session times out while doing inline editing.
Figure 1 and 2 show briefly how inline editing looks to the user. Here are the simple steps that are involved:
- The user logs into the application
- The user opens up the edit form
- The user starts editing and then gets a craving for a venti gingerbread latte
- The user returns 45 minutes and one latte later and submits the form
Figure 1: Inline AJAX editing closed
Figure 2: Inline AJAX editing open
Most applications have a session duration of around 30 minutes. The user from the scenario above has obviously lost their session and with it their credentials, which are usually stored in the session. At this point the user must log back into the application in order to continue working, and hopefully the application saves the work they did before they went out for coffee. The issue here is that the processing in the browser is occuring in AJAX and the response from the server is normally displayed within a specific element in the XHTML document (usually a DIV or P element). Therefore, the login process must be complete AJAXified in order to provide the correct user experience.
The General Solution
The general solution to this problem, that is if you have built a custom authentication and authorization package and need to add AJAX support to it, is to create two sets of JSP pages, one for normal login and one for AJAX login. The reason two sets are required is that normal login pages are complete XHTML documents that include HEAD, BODY, and HTML tags. AJAX login does not need the entire XHTML document. Rather an AJAX login form should be just that, only the login form.
Listing 1 illustrates what a simple normal login form might look like, while listing 2 illustrates an AJAX login form. Notice that listing 2 only contains the FORM element and its children, while listing 1 contains an entire XHTML document.
xml 代码 - <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head><title>Non-AJAX Login form</title></head>
- <body>
- <h1>This is the full login page! Login dude!</h1>
- <form action="/secure/custom_security_check">
- Username: <input type="text" name="j_username"/><br/>
- Password: <input type="text" name="j_password"/><br/>
- <input type="submit" name="Login" value="Login"/>
- </form>
- </body>
- </html>
Listing 1: Normal login form
- <form action="/secure/custom_ajax_security_check" id="ajax-form">
- Username: <input type="text" name="j_username"/><br/>
- Password: <input type="text" name="j_password"/><br/>
- <input type="submit" name="Login" value="Login"
- onclick="return ajax_submit_form();"/>
- </form>
Once you have have two login pages, one for normal login and one for AJAX login, some mechanism for determining whether or not a request is an AJAX request must be constructed. I prefer using regular expressions whenever possible because of their flexibility, but any mechanism that can distinquish requests based on the incoming URL is all that is needed. It is also important to select a naming standard for AJAX URLs. This will make the process of controlling AJAX authentication much simpler. My standard is to prepend all URLs with ajax for AJAX requests. Figure 3 shows an example URL.
http://www.example.com/profile/ajax_update_info.action
Usually a servlet filter chain is attached to secured resources to check if the user is logged in. Once you have a naming standard and the AJAX login pages, adding code to this filter to determine if the URL is an AJAX request will determine which set of login pages to take the user to. Listing 3 illustrates how a simple filter method might look.
java 代码 - public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
- throws Exception{
- if (req.getSession().getAttribute("user") == null) {
- if (req.get\RequestURI().matches("^ajax.*")) {
- RequestDispatcher rd = req.get\RequestDispatcher("/login/ajax_login.jsp");
- rd.forward(req, res);
- } else {
- res.sendRedirect("/login/login.jsp");
- }
- return;
- }
- }
Listing 3: Simple authorization filter Method
ACEGI Solution
The website I was working on when I first came across this issue was http://www.naymz.com and the majority of the editing is done inline. Naymz uses ACEGI (http://www.acegisecurity.org) for authentication and authorization and as it turns out ACEGI handles this situation quite easily. The key to understanding how ACEGI can be configured to handle AJAX authentication is understand how ACEGI handles each request that comes into the servlet container. Each request is passed to an ACEGI filter chain, which is almost identical to the J2EE servlet filter chains most are familiar with. This filter chain is normally defined in the Spring configuration file using the FilterChainProxy bean. This bean is configured by setting up filter chains to respond to specific URL patterns. These patterns are defined either using the Apache Ant syntax or regular expressions. For this article I will be using the the Ant syntax. Listing 4 shows a simple configuration that has a single filter chain for all requests.
xml 代码 - <bean id="filter\ChainProxy" class="org.acegisecurity.util.FilterChainProxy">
- <property name="filter\InvocationDefinitionSource">
- <value>
- CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
- PATTERN_TYPE_APACHE_ANT
- /**=saved\RequestFilter, ..., authentication\ProcessingFilter, ...,
- exception\TranslationFilter, ...
- </value>
- </property>
- </bean>
Listing 4: ACEGI configuration
The line that starts with /**= tells the ACEGI framework to send all requests to this filter chain. The chain is defined by a comma separated list of bean ids. Each filter in the chain is called by ACEGI to handle different aspects of the authentication from checking if the user is logged in and taking them to the login page if not, to authentication and authorization. Recall that in order to handle AJAX login correctly we needed a mechanism for determining if a request is an AJAX request. In order to accomplish this in ACEGI, we add an additional line to the FilterChainProxy configuration to construct a new filter chain for AJAX requests. Listing 5 illustrates this configuration.
xml 代码 - <bean id="filter\ChainProxy" class="org.acegisecurity.util.FilterChainProxy">
- <property name="filter\InvocationDefinitionSource">
- <value>
- CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
- PATTERN_TYPE_APACHE_ANT
- /**/*ajax*=saved\RequestFilter, ..., ajax\AuthenticationProcessingFilter, ...,
- ajax\ExceptionTranslationFilter, ...
- /**=saved\RequestFilter, ..., authentication\ProcessingFilter, ...,
- exception\TranslationFilter, ...
- </value>
- </property>
- </bean>
Listing 5: AJAX FilterChainProxy Configuration
The configuration now tells ACEGI that any URL that contains ajax should use the new filter chain. Now that ACEGI is able to handle AJAX requests separately from normal requests, we need to configure the rest of ACEGI for AJAX. There are two filters in the ACEGI authentication process that will need tweaking for AJAX authentication to work. If you notice from listing 5, the AJAX filter chain defines two new filters whose names contains ajax. These filters handle failed authorization and login and once defined will allow AJAX authentication with ACEGI.
One filter in almost all chains is the ExceptionTranslationFilter. This filter handles the failed authorization step. This step occurs when a resource is being requested that requires the user to be logged in but the user is not yet logged in. In this case the ExceptionTranslationFilter catches an AuthenticationException from a filter farther down the chain and takes the user to the login page. Since AJAX applications have a special login page for AJAX requests, a second ExceptionTranslationFilter must be defined that uses the AJAX login page. ExceptionTranslationFilter is configured by a reference to an EntryPoint, which is the ACEGI version of the login page. Listing 6 shows the configuration for the new ExceptionTranslationFilter and the EntryPoint for the AJAX login page.
xml 代码 - <bean id="ajax\ExceptionTranslationFilter"
- class="org.acegisecurity.ui.ExceptionTranslationFilter">
- <property name="authentication\EntryPoint">
- <ref local="ajax\AuthenticationEntryPoint"/>
- </property>
- </bean>
- <bean id="ajax\AuthenticationEntryPoint"
- class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
- <property name="login\FormUrl" value="/login/ajax_login.jsp"/>
- </bean>
Listing 6: AJAX ExceptionTranslationFilter configuration
Notice that in listing 6 the EntryPoint references the /login/ajax_login.jsp JSP page. This JSP contains the AJAX login for from listing 8 (listing 7 contains the ACEGI normal login form). If you are planning on using ACEGI 1.0.3 or later, a feature has been added so that EntryPoints can be forwarded to rather than redirected to by ACEGI. This can reduce round trips to the server by the browser and speed up AJAX login a bit. To turn this on set the property named serverSideRedirect to false on the AJAX EntryPoint.
xml 代码 - <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head><title>Non-AJAX Login form</title></head>
- <body>
- <h1>This is the full login page! Login dude!</h1>
- <form action="/secure/j_acegi_security_check">
- Username: <input type="text" name="j_username"/><br/>
- Password: <input type="text" name="j_password"/><br/>
- <input type="submit" name="Login" value="Login"/>
- </form>
- </body>
- </html>
Listing 7: ACEGI normal login form
xml 代码 - <form action="/secure/j_acegi_ajax_security_check" id="ajax-form">
- Username: <input type="text" name="j_username"/><br/>
- Password: <input type="text" name="j_password"/><br/>
- <input type="submit" name="Login" value="Login"
- onclick="return ajax_submit_form();"/>
- </form>
Listing 8: ACEGI AJAX login form
The final step to configuring ACEGI is to configure a new AuthenticationProcessingFilter. This class handles the submission of the login form, validation of the user credentials and either resubmitting the user’s original request, taking the user to a default success page or handling any login errors. There are three configuration parameters used by this filter that will need tweaking. These are authenticationFailureUrl, defaultTargetUrl and filterProcessesUrl.
The filterProcessesUrl parameter controls the URL that is used by the login form. One tricky thing to remember is that the login for is an AJAX inline form and therefore must be handled by our new filter chain. Therefore it must contain ajax somewhere in the URL. A good default URL to use is /secure/j_ajax_acegi_security_check. This URL contains ajax and therefore will be sent to the correct filter chain.
Also, because the AJAX login form is being handled inline, the failure and success pages must also be XHTML snippets so that the login process is rendered correctly by the browser. Therefore, these two configuration parameters must be configured to use special AJAX pages. Listing 9 shows the AJAX AuthenticationProcessingFilter configuration.
xml 代码 - <bean id="ajax\AuthenticationProcessingFilter"
- class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
- <property name="authenticationManager" ref="authenticationManager"/>
- <property name="authentication\FailureUrl" value="/login/ajax_login_failed.jsp"/>
- <property name="default\TargetUrl" value="/login/ajax_login_successful.jsp"/>
- <property name="filter\ProcessesUrl" value="/secure/j_ajax_acegi_security_check"/>
- </bean>
Listing 9: AJAX AuthenticationProcessingFilter configuration
Notice that listing 9 defines special AJAX JSPs for failed and successful login. These JSPs, like the AJAX login JSP, contain only XHTML snippets and are show in listing 10.
xml 代码 - <!-- ajax_login_failed.jsp -->
- Login FAILED!<br/>
- <form action="/secure/j_ajax_acegi_security_check" id="ajax-form">
- Username: <input type="text" name="j_username"/><br/>
- Password: <input type="text" name="j_password"/><br/>
- <input type="submit" name="Login" value="Login" onclick="return ajax_submit_form();"/>
- </form>
-
- <!-- ajax_login_successful.jsp -->
- Login successful!<br/>
Listing 10: AJAX success and failure JSPs
Saved Request
One final thing I should mention is that ACEGI 1.x handles saving the users original request during the login process so that it can be re-executed once the user has logged in successfully. This mechanism uses redirects for normal requests and normal login. Using the configuration described above to achieve AJAX login, any application that wishes to use the saved request feature of ACEGI for AJAX login can. Browsers handle redirects within AJAX processing in the same manner as they do for normal requests and therefore after the user has successfully logged in, the AJAX processing will handle the saved request. As long as the AJAX filter chain is configured for saved requests, no extra configuration is required.
Conclusion
AJAX applications allow users a better experience and can greatly reduce the bandwidth and processing power required of servers. However, AJAX applications suffer from the fact that if user sessions expire and their credentials are lost, they must have a method of re-logging into the application within the bounds of the AJAX processing that they are currently performing. This mechanism is simple to implement by hand or with the ACEGI security framework. Using the configuration above, the ACEGI framework can easily and quickly handle AJAX authentication allowing users to login using an AJAX inline form. Furthermore, ACEGI’s saved request feature can be configured so that work that is done inline and submitted via AJAX is not lost if the users session expires.
发表评论
-
Spring Milestone Maven Repository地址
2009-05-11 10:52 7769使用maven又想试用spring 3.0 m3的朋友可以用s ... -
HiddenHttpMethodFilter:自动转换Http Method
2009-03-29 11:21 5428REST的核心之一就是提供统一接口,也就是说对所有的资源(UR ... -
ActiveMQ5.0实战三:使用Spring发送,消费topic和queue消息
2008-08-28 18:21 32959ActiveMQ5.0实战一: 安装配 ... -
The smallwig theory of optimization
2008-04-17 09:49 1316There are three kinds of optimi ... -
ElementType.LOCAL_VARIABLE目前基本没用
2008-04-07 18:30 3839jdk5.0引入Annotation语法,@Target中的E ... -
Memcached java client 2.01发布
2008-04-05 21:39 2327com.danga.MemCached 发布2.0.1包括许多 ... -
Struts2中使用Stream Result Type
2008-04-05 18:25 18062Stream result type是Struts2中比较有用 ... -
NotSerializableException: EnhancerByCGLIB
2008-04-03 12:23 4197使用Ibatis时,为了获得更好的性能,我们一般都会将enha ... -
Pointcut命名有可能导致错误
2008-02-28 19:16 4243使用Spring @AspectJ方式的AOP,代码@Aspe ... -
异常通知:面向方面的模型
2008-02-28 15:16 2137原文:http://dev2dev.bea.com ... -
Sping容器加载xsd文件时的问题
2008-01-31 17:56 6300今天遇到一个非常奇怪的spring容器问题,先看日志]-303 ... -
关于memcached client的选择
2008-01-10 15:29 13483Memcached(http://www.danga.com/ ... -
Java确实不适合于作为主要编程教学语言
2008-01-10 12:12 1594最近米国那边又在讨论这个话题, 孟岩也发了一篇帖子http:/ ... -
Spring 2.5Annotation使用基本类型和${}
2008-01-08 19:08 2698最近使用了Spring2.5 annotation风格的DI, ... -
ActiveMQ5.0实战二: 基本配置
2008-01-08 17:33 12378/** *作者:andyao,email:andyaoy@gm ... -
JMS消息类型模型
2008-01-04 18:12 9372/**作者:andyao,email:andyaoy@gmai ... -
ActiveMQ5.0实战一: 安装配置ActiveMQ5.0
2008-01-05 18:03 10002/** *作者:andyao,email:andyaoy@gm ... -
Spring Annotation和XML风格的声明式事务
2008-01-04 14:02 5555/***作者:andyao,email:andyaoy@gma ... -
国际化异常消息
2007-12-21 14:26 3809/**作者:andyao,email:andyaoy@gmai ... -
Exception for Action
2007-12-17 16:31 1492原文:http://www.javaworld.com/ja ...
相关推荐
Passwordless Authentication With Golang
现代云端网络攻防 Modern Authentication with Azure Active Directory for Web Applications (Developer Reference)
使用ASP.NET AJAX提供的Authentication Service
基于ASP.NET+AJAX+FormsAuthentication实现的authenticated users 检索。
An Efficient Generic Framework for Three-Factor Authentication With Provably Secure Instantiation
ASP.NET AJAX深入浅出系列课程(15):使用ASP.NET AJAX提供的Authentication Service
ASP.NET AJAX深入浅出系列课程(16):ASP.NET AJAX提供的Authentication Service的实现方式与扩展
Quantum Authentication of Classical Messages with Perfect SecurityQuantum Authentication of Classical Messages with Perfect SecurityQuantum Authentication of Classical Messages with Perfect Security
ssh2 一些错误问题的记录
Arduino Webserver with Authentication Sketch
acegi-security.jar包,
讲座内容: Authentication Service是ASP.NET AJAX提供的另一个Application Service,能够让我们以AJAX方式来使用用户登录等功能。本次课程主要讲述如何来使用Authentication Service。
Authentication Service是ASP.NET AJAX提供的另一个Application Service,能够让我们以AJAX方式来使用用户登录等功能。本次课程主要讲述Authentication Service的简单实现细节以及如何扩展Authentication Service。
redp3816_Flexible authentication solution with IBM Tivoli Directory Integrator and IBM WebSphere Portal.pdf
remote user authentication scheme with forward secrecy, which provides forward secrecy to the long term secret key of the authentication server. This scheme is also secure against Chan – Cheng and ...
A Novel RFID Authentication Protocol with Ownership Transfer Han Jia1, Jun Wen2 School of Computer Science and Technology, University of Electronic Science and Technology of China,Chengdu, China 1...
Quantum authentication of classical messagesQuantum authentication of classical messagesQuantum authentication of classical messages
Acegi是Spring Framework 下最成熟的安全系统,它提供了强大灵活的企业级安全服务,如: 1 : 完善的认证和授权机制, 2 : Http资源访问控制, 3 : Method调用访问控制, 4 : Access Control List (ACL) 基于对象...
Kubernetes RBAC with Openssl Authentication 介绍k8s的认证授权机制
HTTPS连接时,采用证书认证时的双向握手协议过程分析。