`
guoyiqi
  • 浏览: 1009397 次
社区版块
存档分类
最新评论

Spring Security 设置session

阅读更多

使用SecurityContextHolder来偷窥登入帐号密码,手段还真是不够文雅。 Spring-Security3是有提供取得登入资讯塞到Session的实践,不过写起来很烦,很烦也大概不易被破解^^。 Google这方面的资讯,不是缺漏,就是讲述古早的版本,还有中文网站,资讯虽新,却常出现文章一大抄的谬误,我目前是用3.0.2版,和3.0.1、3.0 .0差异何在也不知,不过至少我这方面有踹通,实践方式和Google内容还是有些关键性的差异:

第一个应该是security-context.xml的设定了:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
    
<http use-expressions="true" auto-config="true">
        
<intercept-url pattern="/*.do" access="hasRole('ROLE_USER')"/>
        
<intercept-url pattern="/login.jsp" access="isAnonymous()"/>
        
<intercept-url pattern="/**" access="permitAll"/>
        
<form-login login-processing-url="/j_spring_security_check"
         
login-page="/login.jsp" default-target-url="/echo.do"
         
authentication-failure-url="/login.jsp?error=1"/>
        
<logout logout-url="/j_spring_security_logout" logout-success-url="/login.jsp"/>
        
<custom-filter before="FORM_LOGIN_FILTER" ref="authenticationProcessingFilter"/>
        
<session-management invalid-session-url="/timeout.html">
            
<concurrency-control max-sessions="1" />
        
</session-management>
    
</http>
    
<authentication-manager alias="authenticationManager">
        
<authentication-provider user-service-ref="securityManager"/>
    
</authentication-manager>
    
<beans:bean id="securityManager"
        
class="com.foo.dao.impl.UserDetailsS​​erviceImpl"/>
    
<beans:bean id="authenticationProcessingFilter"
        
class="org.springframework.security.web.authentication.UsernamePasswordAut​​henticationFilter">
        
<beans:property name="authenticationManager" ref="authenticationManager"/>
        
<beans:property name="authenticationSuccessHandler">
            
<beans:bean class="com.foo.security.MyAuthenticationSuccessHandler">
                
<beans:property name="d​​efaultTargetUrl" value="/echo.do"/>
            
</beans:bean>
        
</beans:property>
        
<beans:property name="filterProcessesUrl" value="/j_spring_security_check"/>
    
</beans:bean>
</beans:beans>
 

红字是之前SecurityContextHolder饭粒多出来的设定,真正是靠腰的多。 <http>标签多出<custom-filter>指向authenticationProcessingFilter这个bean,而Google的before后所接的定字几乎都错,都是这么写:

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

可是Filter的列举(枚举)型态里,根本没这有AUTHENTICATION_PROCESSING_FILTER这号人物,其它的参考下列表,我原本用CONCURRENT_SESSION_FILTER过不了关,后来改成FORM_LOGIN_FILTER才Pass,Spring-Seucrity 3这部份很像Struts2的Interceptor Stack,从下表来看,应该​​是有顺序,LOGOUT_FILTER排在FORM_LOGIN_FILTER之前…嗯~~也蛮合理的。

Enumerated Values​​ :
    
- FIRST
    
- CHANNEL_FILTER
    
- CONCURRENT_SESSION_FILTER
    
- SECURITY_CONTEXT_FILTER
    
- LOGOUT_FILTER
    
- X509_FILTER
    
- PRE_AUTH_FILTER
    
- CAS_FILTER
    
- FORM_LOGIN_FILTER
    
- OPENID_FILTER
    
- BASIC_AUTH_FILTER
    
- SERVLET_API_SUPPORT_FILTER
    
- REMEMBER_ME_FILTER
    
- ANONYMOUS_FILTER
    
- EXCEPTION_TRANSLATION_FILTER
    
- SESSION_MANAGEMENT_FILTER
    
- FILTER_SECURITY_INTERCEPTOR
    
- SWITCH_USER_FILTER
    
- LAST
 

<custom-filter>选择FORM_LOGIN_FILTER时机委给Bean-authenticationProcessingFilter使用,这一动作出现频道盖台,<form-login>标签应该失效,委给authenticationProcessingFilter处理。 authenticationProcessingFilter显然是指定org.springframework.security.web.authentication.UsernamePasswordAut​​henticationFilter来处理的,此处在Google上又会得到错误类别名,正名是UsernamePasswordAut​​henticationFilter,而Google的类别名是UsernamePasswordAut​​henticationProcessingFilter,多出了Processing,所以我才猜是不是前版的遗留,至少在3.0.2版没这个类别。

authenticationProcessingFilter要指定三类properties,第一个是指定Authentication Manager。若非这次的需求,SecurityContextHolder会找到<authentication-manager>这个标签作为预设值。但既然委托给Spring Bean处理,所以要有的bean reference的name,所以后来才在<authentication-manager>加个alias属性,这样<authentication-manager>才能被authenticationProcessingFilter找到。

authenticationProcessingFilter要指定的第二类properties是本篇文章目的主程式所在,储存username至session。最多有四种bean,最常用的是认证成功(AuthenticationSuccessHandler)和认证失败(AuthenticationFailureHandler),尚有未认证的访问及已认证访问受保护的URL。而储存至session的动作在第一种,是故AuthenticationSuccessHandler属性指向MyAuthenticationSuccessHandler这个类别,其实作如下:

public class MyAuthenticationSuccessHandler extends
        
SavedRequestAwareAuthenticationSuccessHandler {
    
@Override
    
public void onAuthenticationSuccess(HttpServletRequest request,
            
HttpServletResponse response, Authentication authentication)
            
throws ServletException, IOException {
        
HttpSession session = request.getSession();
        
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        
session.setAttribute("username", userDetails.getUsername());
        
super.onAuthenticationSuccess(request, response, authentication);
    
}
}
 

和前一篇SecurityContextHolder饭粒原理是一样,只是比较文雅,而MyAuthenticationSuccessHandler下设了一个defaultTargetUrl属性,其实也恰恰覆盖<form-login>的default-target-url属性。先前有言,<customer-filter>若设置为CONCURRENT_SESSION_FILTER过不了关,是session值在onAuthenticationSuccess的设定无法带给defaultTargetUrl,所以改成FORM_LOGIN_FILTER就可以work。

第三类是filterProcessesUrl属性,指authenticationProcessingFilter会对哪个URL Pattern产生作用,本例是指/j_spring_security_check,就因为custom-filter设置before="FORM_LOGIN_FILTER"抢在<form-login>拦截,致使<form-login>失效。

以下是成功配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:s="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"
	default-lazy-init="true">

	<description>SpringSecurity安全配置</description>

	<!-- http安全配置 -->
	<s:http auto-config="true" use-expressions="true">
		<s:intercept-url pattern="/css/**" filters="none" />
		<s:intercept-url pattern="/img/**" filters="none" />
		<s:intercept-url pattern="/js/**" filters="none" />

		<s:intercept-url pattern="/index.jsp" filters="none" />

		<s:intercept-url pattern="/login.action"
			access="hasAnyRole('ROLE_ANONYMOUS')" />
		<s:intercept-url pattern="/logout.jsp"
			access="hasAnyRole('ROLE_ANONYMOUS')" />
		<s:intercept-url pattern="/main/**" access="hasAnyRole('ROLE_通用')" />

		<s:intercept-url pattern="/public*"
			access="hasAnyRole('ROLE_ANONYMOUS')" />

		<s:intercept-url pattern="/public/test.action"
			access="hasAnyRole('ROLE_ANONYMOUS')" />

		<s:intercept-url pattern="/**" access="isAuthenticated()" />

		<s:intercept-url pattern="/account/user!setSession*"
			access="hasAnyRole('ROLE_通用')" />
		<s:intercept-url pattern="/account/user!changepwd*"
			access="hasAnyRole('ROLE_通用')" />

		<s:intercept-url pattern="/account/user!save*" access="hasAnyRole('ROLE_修改用户')" />
		<s:intercept-url pattern="/account/user!delete*"
			access="hasAnyRole('ROLE_修改用户')" />
		<s:intercept-url pattern="/account/user*" access="hasAnyRole('ROLE_浏览用户')" />

		<s:intercept-url pattern="/account/role!save*" access="hasAnyRole('ROLE_修改角色')" />
		<s:intercept-url pattern="/account/role!delete*"
			access="hasAnyRole('ROLE_修改角色')" />
		<s:intercept-url pattern="/account/role*" access="hasAnyRole('ROLE_浏览角色')" />

		<s:intercept-url pattern="/lab/lab!save*" access="hasAnyRole('ROLE_修改实验室')" />
		<s:intercept-url pattern="/lab/lab!delete*" access="hasAnyRole('ROLE_修改实验室')" />
		<s:intercept-url pattern="/lab/lab*" access="hasAnyRole('ROLE_浏览实验室')" />

		<s:form-login login-page="/login.action"
			default-target-url="/main.action" authentication-failure-url="/login.action?error=true" />
		<s:logout logout-success-url="/logout.jsp" />

		<s:custom-filter before="FORM_LOGIN_FILTER" ref="appSessionProcessingFilter" />
	</s:http>



	<!-- 自定义成功和失败处理器,AppSessionSuccessHandler中设置了session -->
	<bean id="appSessionProcessingFilter"
		class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
		<property name="authenticationFailureHandler">
			<bean
				class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
				<property name="defaultFailureUrl" value="/pages/Login/login.do?error=true" />
			</bean>
		</property>
		<property name="authenticationSuccessHandler">
			<bean class="mis.service.account.AppSessionSuccessHandler">
				<property name="defaultTargetUrl" value="/" />
			</bean>
		</property>
		<property name="authenticationManager" ref="authenticationManager"/>
        <property name="filterProcessesUrl" value="/j_spring_security_check"/>
	</bean>


	<!-- 认证配置, 使用userDetailsService提供的用户信息 -->
	<s:authentication-manager alias="authenticationManager">
		<s:authentication-provider user-service-ref="userDetailsService">
			<s:password-encoder hash="plaintext" />
		</s:authentication-provider>
	</s:authentication-manager>

	<!-- 项目实现的用户查询服务 -->
	<bean id="userDetailsService" class="mis.service.account.UserDetailsServiceImpl" />
</beans>

 

package mis.service.account;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import mis.dao.account.UserDao;
import mis.entity.account.User;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;

public class AppSessionSuccessHandler extends
		SavedRequestAwareAuthenticationSuccessHandler {
	@Autowired
    private UserDao userDao;
	@Override 
	public void onAuthenticationSuccess(HttpServletRequest request,HttpServletResponse response,Authentication authentication)throws ServletException,IOException{
		HttpSession session=request.getSession();
		UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        User currentUser = userDao.findUnique("loginname", userDetails.getUsername().toString());
        session.setAttribute("currentUser", currentUser);
        
        System.out.println("do it success");

	super.onAuthenticationSuccess(request,response,authentication);}
	public UserDao getUserDao() {
		return userDao;
	}
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}}

 

 

分享到:
评论
1 楼 macjava85 2011-08-31  
强人,理解的很深刻

相关推荐

    Springboot+SpringSecurity+SpringSession+Redis+Mybatis-Plus+Swwager.zip

    本项目“Springboot+SpringSecurity+SpringSession+Redis+Mybatis-Plus+Swwager”整合了Spring Boot、Spring Security、Spring Session、Redis、Mybatis-Plus以及Swagger等技术,旨在构建一个强大的、安全的、具有...

    SpringBoot集成Spring Security登录管理 添加 session 共享【完整源码+数据库】

    我们将基于给定的标签——SpringBoot、SpringSecurity、mysql、session共享和idea来构建一个完整的示例。 首先,SpringBoot是一个轻量级的Java框架,它简化了创建独立的、生产级别的基于Spring的应用程序。通过内置...

    基于java config的springSecurity 六 集成spring session

    参考资料: http://docs.spring.io/spring-session/docs/current-SNAPSHOT/reference/html5/guides/security.html http://blog.csdn.net/xiejx618/article/details/43059683

    Spring Security2中设置Cookie的保存时间

    这个文件包含了Spring Security的核心配置,包括访问控制、认证机制以及Cookie的相关设置。 在`spring-base.xml`中,我们可以通过以下方式来设置Cookie的保存时间: ```xml &lt;!-- 其他配置 --&gt; &lt;session-...

    spring security 完整项目实例

    session配置在Spring Security中至关重要。它可以控制会话的最大并发数量,防止会话固定攻击,并可以设置会话超时策略。使用HttpSessionAuthenticationStrategy和SessionManagementConfigurer,我们可以精细化管理...

    Spring Cloud Gateway 整合 Spring Security 统一登录认证鉴权

    在压缩包文件`spring_gateway_security_webflux`中,可能包含了示例代码或配置文件,用于演示如何在Spring Cloud Gateway中集成Spring Security,实现统一登录认证鉴权。这些资源可以帮助开发者更快地理解和实践上述...

    springsecurity学习笔记

    在"springsecurity学习笔记"中,你可能会涉及以下主题: - Spring Security的基本配置,包括web安全配置和全局安全配置。 - 如何自定义认证和授权流程,比如实现自定义的AuthenticationProvider和...

    利用spring security控制同一个用户只能一次登陆

    &lt;listener-class&gt;org.springframework.security.web.session.HttpSessionEventPublisher ``` 3. **自定义SessionAuthenticationStrategy**: 实现`SessionAuthenticationStrategy`接口,当用户尝试登录时,检查...

    spring security 官方文档

    4. **会话管理(Session Management)**:Spring Security提供了强大的会话管理功能,可以限制同一用户同时在线的数量,检测会话劫持和会话固定攻击,并能实现会话超时策略。 5. **CSRF保护(Cross-Site Request ...

    spring spring security2.5 jar

    4. **会话管理**:Spring Security提供了会话管理功能,可以防止会话固定攻击(Session Fixation)、实现会话超时以及单点登录(Single Sign-On, SSO)。 5. **异常处理**:当安全规则不满足时,Spring Security会...

    spring-security 官方文档 中文版

    Spring Security 是一款基于 Spring 框架的安全插件,提供了完整的安全性解决方案,包括身份认证(Authentication)、授权(Authorization)以及会话管理(Session Management)等功能。Spring Security 的设计目标是为...

    spring security3 中文版本

    ### Spring Security 3.0.1 中文版知识点解析 #### 一、Spring Security 3.0.1 概览 ##### 1.1 Spring Security 是什么? Spring Security 是一个强大的、高度可定制的身份验证和访问控制框架。它提供了许多功能...

    SpringBoot+SpringSecurity+WebSocket

    3. 集成SpringSecurity:配置SpringSecurity的WebSecurityConfigurerAdapter,设置登录认证、权限控制等规则。确保WebSocket连接也需要经过SpringSecurity的认证。 4. 客户端支持:在前端JavaScript中使用WebSocket ...

    spring security 3.x session-management 会话管理失效

    Spring Security可以通过配置`&lt;session-config&gt;`元素或使用`HttpSessionEventPublisher`监听器来设置会话超时时间。 4. **会话并发控制** - 会话并发控制限制了同一用户在同一时间可以活跃的会话数量,防止会话...

    springsecurity原理流程图.pdf

    认证成功后,Spring Security会将认证信息存储在session中,并通过调用sessionStrategy.onAuthentication方法来处理与session相关的操作。 b. 最终,会执行successfulAuthentication方法,该方法可以被子类覆盖以...

    springSecurity 实现传参

    Spring Security 是一个强大的和高度可定制的身份验证和访问控制框架,用于Java应用程序。在这个场景中,我们关注的是如何使用Spring Security实现登录验证以及在登录过程中传递参数,特别是记录并返回用户登录前的...

    初识 Spring Security - v1.1.pdf

    - **概念**:Spring Security 提供了丰富的session管理机制,包括检测session超时、并发控制以及防止session固定攻击等功能。 - **检测session超时**:当session超时时,可以通过配置自动清除用户认证信息。 - **...

    SpringSecurity中文文档.zip

    此外,SpringSecurity还提供了会话管理功能,包括会话固定保护(Session Fixation Protection)和会话超时(Session Timeout)等,以防止会话劫持和会话固定攻击。它还集成了Remember Me服务,允许用户在一定时间内...

    spring-boot mybaits spring security redis整合

    spring security权限管理。 aop日志记录。 4、调度 ====== Spring task, 可以查询已经注册的任务。立即执行一次任务。 5、缓存和Session =========== 注解redis缓存数据,Spring-session和redis实现分布式...

    Spring Security OAuth2.0学习笔记.zip

    Spring Security OAuth2.0学习笔记 什么是认证、授权、会话。 Java Servlet为支持http会话做了哪些事儿。 基于session认证机制的运作流程。 基于token认证机制的运作流程。 理解Spring Security的工作原理,Spring ...

Global site tag (gtag.js) - Google Analytics