1:需求:客户使用用户名、密码登录,根据不同的错误类型,在页面提示相应的错误信息
(一) 同一帐号IP或者密码450内3次登录,提示:请450秒后再进行登录
(二) 450内登录失败大于等于3次登录,提示:帐号被设为冻结
(三) 450秒内密码连续3次错误,提示:帐号禁止15分钟内再登录 .............
2:采用技术:acegi-security-1.0.7.jar
3:问题描述: (一) 如何将acegi登录认证的错误信息,输出给用户。
4:参考的资料:http://jiwenke.iteye.com/blog/112979
5:解决方案:采用Acegi提供的异常来处理。
6:核心步骤:
(一)新建一个自己的类如(XXAuthenticationProcessingFilter)继承acegi的类org.acegisecurity.ui.webapp.AuthenticationProcessingFilter,同时覆盖父类的3个方法, 关键是覆盖父类的protected void unsuccessfulAuthentication(HttpServletRequest request,HttpServletResponse response, AuthenticationException failed)方法 。。。。。。。。。 String validMessage = failed.getMessage(); //provider处理中抛出的异常,供web页面处理提示信息 logger.info("登录验证出现异常,原因: " + validMessage); SecurityContextHolder.getContext().setAuthentication(null); String failureUrl = getExceptionMappings().getProperty(failed.getClass().getName(), getAuthenticationFailureUrl()); failureUrl += "&validMessage=" + validMessage; // 已参数的形式传递给前端页面 如:xxxx/login.jsp?login_error=1&validMessage=3 。。。。。。。。 补充:XXAuthenticationProcessingFilter类的具体实现参考附件
(二) 修改acegi的配置文件 applicationContext-acegi-security.xml,将authenticationProcessingFilter修改为自己的处理类 <bean id="authenticationProcessingFilter" class="xxx.xxx.xxx.filter.XXAuthenticationProcessingFilter"><property name="authenticationManager">
<ref bean="authenticationManager"></ref>
</property><property name="authenticationFailureUrl"><value>/login.jsp?login_error=1</value></property>
//验证出错跳转的路径己参数
<property name="defaultTargetUrl"><value>/</value></property>
<property name="filterProcessesUrl"><value>/j_acegi_security_check</value></property>
<property name="rememberMeServices"><ref local="rememberMeServices"></ref>
</property><property name="alwaysUseDefaultTargetUrl"><value>false</value></property>
</bean>
(三) authenticationManager中的provider的配置
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers"><list><ref local="memberCardDaoAuthenticationProvider"></ref>
//该provider从数据库中查询用户名、密码进行验证
<ref local="rememberMeAuthenticationProvider"></ref>
<ref local="anonymousAuthenticationProvider"></ref></list>
</property>
</bean>
(四)memberCardDaoAuthenticationProvider的p配置
<bean id="memberCardDaoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService"><ref local="memberCardJdbcImpl"></ref></property>
<property name="userCache"><ref local="userCache"></ref></property>
<property name="passwordEncoder"><ref local="cardPasswordEncoder"></ref></property>
</bean>
(五) memberCardJdbcImpl的配置
<bean id="memberCardJdbcImpl" class="com.milesup.acegi.userdetails.jdbc.MemberCardJdbcImpl">
<property name="dataSource"><ref bean="dataSource"></ref></property>
<property name="loginLogService"><ref bean="loginLogService"></ref></property>
/MemberCardJdbcImpl具体处理验证的类需要注入的service
<property name="rolePrefix"><value>ROLE_</value></property>
</bean>
补充:MemberCardJdbcImpl继承了org.acegisecurity.userdetails.jdbc.JdbcDaoImpl类,同时覆盖该类的 public UserDetails loadUserByUsername(String userInfo) throws ValidateException 在该方法中真正实现数据库用户名、密码进行验证 注意:该方法抛出来一个自定义的异常类,该类继承了org.acegisecurity.AuthenticationException,用于抛出异常XXAuthenticationProcessingFilter类中方法unsuccessfulAuthentication 要处理的异常,详细参考附件XXAuthenticationProcessingFilter类的详细信息。 7: 页面处理 $(document).ready(function(){ if (${param.login_error == 1}) { if (${param.validMessage == 2}){ $('#error_id').html('登录失败:同一帐IP或者密码450内3次登录,请8分钟后再进行登录'); } else if (${param.validMessage == 3}){ $('#error_id').html('登录失败:450内登录失败大于等于3次登录,帐号被设为冻结'); } else if (${param.validMessage == 4}){ $('#error_id').html('登录失败:450秒内密码连续3次错误,15分钟内禁止登录'); } else if (${param.validMessage == 5}){ $('#error_id').html('登录失败:15分钟内禁止登录'); } else if (${param.validMessage == 6}){ $('#error_id').html('登录失败:用户名、密码、号码类型不正确'); } } });
总结:以上是这两天工作中接触acegi处理的问题,主要提供给自己一个回忆的纪要,如果写得不好误导了来访的朋友或者耽误了您的时间,敬请谅解。 排版太难看了,有时间再来整过。。。。。。