`

springMVC+spring security3对于登入后处理的实现

阅读更多

直接进入主题吧,有个需求就是记录用户登入的ip和时间及总共的登入次数。这个需求很普通,但是在应用了springsecurity后,我还真一下子找不到该在哪处下手。

 

习惯性的看了下security的filters

filters ArrayList<E>  (id=124)
elementData Object[11]  (id=140)
[0] SecurityContextPersistenceFilter  (id=142)
[1] LogoutFilter  (id=144)
[2] UsernamePasswordAuthenticationFilter  (id=146)
[3] DefaultLoginPageGeneratingFilter  (id=151)
[4] BasicAuthenticationFilter  (id=153)
[5] RequestCacheAwareFilter  (id=155)
[6] SecurityContextHolderAwareRequestFilter  (id=157)
[7] AnonymousAuthenticationFilter  (id=159)
[8] SessionManagementFilter  (id=161)
[9] ExceptionTranslationFilter  (id=163)
[10] FilterSecurityInterceptor  (id=165)
modCount 11
size 11

 对security稍微熟习的就知道主要的验证工作是在

UsernamePasswordAuthenticationFilter  (id=146

 这个filter中完成的。

 

下面简单说一下这个流程:

 

在这个filter中,主要执行attemptAuthentication这个方法

public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
      ......

        return this.getAuthenticationManager().authenticate(authRequest);
    }

 注意最后一句,在此处得到AuthenticationManager对象 ,也就是我们在xml文件中定义的

<authentication-manager alias="authenticationManager">
		<authentication-provider user-service-ref="websiteUserDetailsService" />
 </authentication-manager>
 

而AuthenticationManager中最要紧的便是那些providers ,此处是源码

public Authentication doAuthentication(Authentication authentication) throws AuthenticationException {
        Class<? extends Authentication> toTest = authentication.getClass();
        AuthenticationException lastException = null;
        Authentication result = null;

        for (AuthenticationProvider provider : getProviders()) {
            if (!provider.supports(toTest)) {
                continue;
            }

            logger.debug("Authentication attempt using " + provider.getClass().getName());

            try {
                result = provider.authenticate(authentication);

                if (result != null) {
                    copyDetails(authentication, result);
                    break;
                }
            } catch (AccountStatusException e) {
                // SEC-546: Avoid polling additional providers if auth failure is due to invalid account status
                eventPublisher.publishAuthenticationFailure(e, authentication);
                throw e;
            } catch (AuthenticationException e) {
                lastException = e;
            }
        }

        if (result == null && parent != null) {
            // Allow the parent to try.
            try {
                result = parent.authenticate(authentication);
            } catch (ProviderNotFoundException e) {
                // ignore as we will throw below if no other exception occurred prior to calling parent and the parent
                // may throw ProviderNotFound even though a provider in the child already handled the request
            } catch (AuthenticationException e) {
                lastException = e;
            }
        }

        if (result != null) {
            eventPublisher.publishAuthenticationSuccess(result);
            return result;
        }

        // Parent was null, or didn't authenticate (or throw an exception).

        if (lastException == null) {
            lastException = new ProviderNotFoundException(messages.getMessage("ProviderManager.providerNotFound",
                        new Object[] {toTest.getName()}, "No AuthenticationProvider found for {0}"));
        }

        eventPublisher.publishAuthenticationFailure(lastException, authentication);

        throw lastException;
    }

我们通过在xml中配置:

<authentication-manager alias="authenticationManager">
		<authentication-provider user-service-ref="websiteUserDetailsService" />
		<authentication-provider>
			<jdbc-user-service data-source-ref=""/>
		</authentication-provider>
		<authentication-provider>
			<ldap-user-service/>
		</authentication-provider>
  </authentication-manager>

 来提供多个provider

 

 

好了接下来就是关键了:

 

首先我们在<http/>中添加自己的filter,注意是before,如果是position要报错

<custom-filter before="FORM_LOGIN_FILTER" ref="authenticationProcessingFilter"/>

 

然后添加:

<beans:bean id="authenticationProcessingFilter" class="com.mxdba.app.common.springsecurity.MyUsernamePasswordAuthenticationFilter">
	  <beans:property name="authenticationSuccessHandler" ref="authenticationSuccessHandler"></beans:property>
	  <beans:property name="authenticationFailureHandler" ref="authenticationFailureHandler"></beans:property>
	  <beans:property name="authenticationManager" ref="authenticationManager"></beans:property>
</beans:bean>
 

这里的

authenticationSuccessHandler

 就是我们可以动刀子的地方了,注意! 在AbstractAuthenticationProcessingFilter中

private AuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();

 AuthenticationSuccessHandler的字段名是successHandler,但是其set方法是setAuthenticationSuccessHandler,所以property的name是authenticationSuccessHandler

 

然后便是定义我们自己的bean了

<beans:bean id="authenticationSuccessHandler" class="com.mxdba.app.common.springsecurity.MyAuthenticationSuccessHandler"></beans:bean>

 重写onAuthenticationSuccess方法:

public void onAuthenticationSuccess(HttpServletRequest request,
			HttpServletResponse response, Authentication authentication)
			throws ServletException, IOException {
		
		XXXXX//(具体业务逻辑)
		super.onAuthenticationSuccess(request, response, authentication);
	}

 

注意!!!! 这样还不行

 

因为我的authenticationProcessingFilter,是继承自UsernamePasswordAuthenticationFilter,也就是说我其实把UsernamePasswordAuthenticationFilter给废掉了,因为在UsernamePasswordAuthenticationFilter中不是success就是failure。(这个是我自己猜想的)

 

我发现

authentication-failure-url="/login"

 这个已经不起作用了,所以我需要重新在xml申明

<beans:bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
  		<beans:property name="defaultFailureUrl">
  			<beans:value>/login</beans:value>
  		</beans:property>
  </beans:bean>
 

这样就基本OK了

 

 

 

分享到:
评论
6 楼 shadowff 2013-05-12  
http://blog.csdn.net/shadowsick/
可以参考下我基于spring,security的开源系统
security的过滤链可以随意任何位置侵入,方式很简单
5 楼 mxdba321123 2010-09-18  
gogomarine

你说的问题我看了下我当初的配置文件,在<http/>中我没有加auto-config="true",不知是否一定需要显示设置auto-config="false"才可以,有空我去试试,感谢
4 楼 gogomarine 2010-09-18  
引用

注意!!!! 这样还不行

因为我的authenticationProcessingFilter,是继承自UsernamePasswordAuthenticationFilter,也就是说我其实把UsernamePasswordAuthenticationFilter给废掉了,因为在UsernamePasswordAuthenticationFilter中不是success就是failure。(这个是我自己猜想的)


spring中的配置里面,有namespaceParser之类的,如果有 在 <http /> 中配置 auto-config="true"的话,会自动产生 <form-login /> <remember-me />等filters,这样<form-login />就自动的配置了UsernamePasswordAuthenticationFilter ,如果这个设置不去掉的话,再加上自定义的UsernamePasswordAuthenticationFilter这个时候才会报错吧?
3 楼 ycyangcai 2010-09-06  
上面配置也是对的。

我觉得在<form-login> 配置authentication-success-handler-ref 属性比较好!

<form-login login-page="/login" authentication-failure-url="/login?error" default-target-url="/" authentication-success-handler-ref="authenticationSuccessHandler" />
2 楼 mxdba321123 2010-05-03  
感谢 caoyangx 的回复

对于你所说的可能算是一个仁者见仁智者见智的问题了。

我在没有接触security3之前,也看过acegi的书,当时的感觉是“重”。书中有那么一句让我印象很深刻“学acegi,可以顺便很好的复习一下spring的知识”。

不过时隔没多久security3就出来了,我看了pdf,感觉相比acegi来说,轻多了,无论是从配置还是思路上,更清晰,更明了。

我的想法是,springsecurity相当于一层外皮,因为他是filter,其实最大的好处就是对业务逻辑的侵入很小!

所以在粗颗粒的控制完全可以使用springsecurity,而与业务逻辑有相当多的耦合的部分,也完全可以自己再加以实现
1 楼 caoyangx 2010-04-29  
首先说一下,你的思路是对的,做一个过滤器来加入security,实现记录ip和登陆次数,不过看你的描述好像是一个外网项目。
外网项目的权限一般来说比较灵活,我之前也用acegi做了一个外网项目,做了很久,需求也是经常变,最后还是改了很多acegi的源码才实现的。项目完工后,acegi也是面目全非了,得出的结论就是外网项目不如自己来控制权限方便。

相关推荐

    springmvc+springSecurity+mybatis

    在这个"springmvc+springSecurity+mybatis"的整合项目中,Spring MVC负责处理HTTP请求并调用业务逻辑,Spring Security确保了用户访问的安全性,而MyBatis则作为数据访问层,处理与数据库的交互。这种组合为开发者...

    springmvc+spring+hibernate

    3. **配置Spring**:在src/main/resources下创建applicationContext.xml文件,配置Spring的核心容器,包括Bean定义、数据源、事务管理器等。例如,使用DataSource来连接Oracle数据库,使用...

    springMvc+mybatis+springSecurity整合demo

    Spring MVC、MyBatis 和 Spring Security 是 Java Web 开发中常用的三大框架,它们各自负责不同的职责,但在实际项目中常被整合使用以构建强大的企业级应用。本整合 demo 展示了如何将这三个框架协同工作,提供高效...

    maven+springMVC+spring security权限实例

    【标题】"maven+springMVC+spring security权限实例"是一个综合性的IT项目,它展示了如何使用Maven构建一个基于Spring MVC和Spring Security的权限管理应用。这个实例旨在帮助开发者快速理解并实践这三大技术在实际...

    springMVC+springSecurity3.0+maven

    标题 "springMVC+springSecurity3.0+maven" 指的是一个集成项目,它结合了Spring MVC、Spring Security 3.0和Maven这三个关键的Java开发工具和技术。让我们逐一深入理解这些技术及其相互之间的关系。 首先,Spring ...

    springMVC+springsecurity_Demo

    在这个 "springMVC+springsecurity_Demo" 中,我们很可能会看到以下几个关键部分: 1. **配置文件**:通常会有 `spring-servlet.xml`,用于配置 Spring MVC,包括定义 DispatcherServlet、Controllers、...

    springmvc4.0+spring-security3.2+mybatis3.3+mysql整合的登陆功能,

    5. **实现登录逻辑**:在Controller中处理登录请求,调用Spring Security进行认证,验证成功后跳转到相应页面。 这个项目对于理解Spring全家桶的集成和Web应用的安全性有着重要的实践价值。通过实际操作,开发者...

    SpringMVC+springAOP+spring security+Hibernate整合实例代码

    Spring MVC、Spring AOP、Spring Security和Hibernate是Java开发中常用的四大框架,它们各自负责不同的领域,但在实际项目中往往需要进行整合以实现更高效、更安全的开发。本实例代码提供了一个完整的整合示例,涵盖...

    springMVC+spring+Hibernate框架

    此外,Spring的安全模块Spring Security可以用来实现更复杂的权限控制和认证。 总的来说,Spring MVC、Spring和Hibernate的组合提供了一套完整的解决方案,涵盖了Web应用的前端交互、后端业务逻辑和数据库访问。...

    图书管理系统SpringMvc+mybatis

    《图书管理系统SpringMvc+Mybatis实现详解》 在IT领域,构建高效、稳定的软件系统是至关重要的。本项目“图书管理系统”就是这样一个实例,它利用了SpringMvc和Mybatis两大主流框架,为图书管理提供了全面的解决...

    SpringMVC +Security+Hibernate

    Spring Security可以通过配置或注解轻松集成到Spring应用中,实现对URL、方法、表单等的权限控制。例如,你可以使用@Secured或@PreAuthorize注解来定义方法级别的访问控制。 Hibernate则是一个强大的ORM(Object-...

    SpringMVC集成SpringSecurity

    在提供的文件列表“springSecurity3”中,可能包含了实现上述集成步骤的代码示例、配置文件等,通过学习这些文件,你可以更深入地了解SpringMVC与SpringSecurity的集成过程和细节。记住,安全是Web应用的基础,理解...

    SpringMVC+hibernate+Spring

    对于初学者来说,这些都是提升技能的好机会,可以尝试使用Spring Security进行权限控制,使用JavaMailSender发送邮件,或者引入Redis或Memcached进行数据缓存。 总之,这个项目涵盖了SpringMVC、Hibernate和Spring...

    springmvc+mybatis+mysql整合实现列表展示、新增、更新、删除功能

    在实际开发过程中,你可能还需要关注一些其他方面,如安全性(Spring Security)、性能优化(缓存、分页等)、异常处理、日志记录等。不过,本项目作为一个基础框架,已经为你搭建了一个良好的起点,让你能够轻松地...

    SSM框架-详细整合教程(Spring+SpringMVC+MyBatis).pdf

    SSM框架,即Spring、SpringMVC和MyBatis的集成,是Java开发中常见的Web应用程序框架组合。这个框架集合提供了完整的后端解决方案,涵盖了依赖注入(DI)、面向切面编程(AOP)、模型视图控制器(MVC)以及持久层操作...

    spring+springMvc+Mybatis+maven

    在实际开发中,可能还需要集成其他组件,如Spring Security进行安全控制,或者使用Spring Boot简化配置。在项目迭代过程中,保持良好的代码组织和模块化设计,有助于提高项目的可维护性和扩展性。

    Spring+SpringMvc+Mybatis学生管理系统

    在SpringMVC中,可以使用Spring Security或自定义拦截器来实现登录验证。验证成功后,系统会创建一个Session,保存用户信息,以便后续的请求能识别用户身份。 【数据库】 数据库是系统存储数据的地方,这里可能使用...

    springMVC+spring+mybatis

    在SSM框架中,可以使用Spring Security来实现这一功能。 至于ssm_api,这可能是项目中的一个API接口目录,包含了所有对外提供的服务接口定义。在实际开发中,通常会根据业务需求编写RESTful API,使用HTTP方法(GET...

    springMVC注解+ security + redis 实例

    在IT行业中,Spring MVC、Spring Security和Redis是三个非常重要的技术组件,它们分别在Web开发、权限管理和数据缓存方面发挥着关键作用。下面将详细解释这三个技术以及它们如何协同工作。 **Spring MVC** Spring ...

    SpringMVC+Spring+Mybatis+Mysql所需lib包

    这个【标题】"SpringMVC+Spring+Mybatis+Mysql所需lib包"所包含的是一系列必要的库文件,这些文件对于搭建基于这些技术的项目框架至关重要。下面将详细解释这些库的作用和它们在项目中的重要性。 1. **Spring ...

Global site tag (gtag.js) - Google Analytics