Spring Security tutorial session management

 

1.1 Detection session timeout

1.2     concurrency-control

1.3 session fixation attack protection

 

       Spring Security provides support for Http Session management by sub-element under the http session-management element.

 

1.1 Detection session timeout

       Spring Security is used when the user request has timed out sessionId guide the user to a specific page. This can be achieved by the following configurations.

   <security:http>

      ...

      <-! Session management, invalid-session-url specifies the use of sessionId has timed out a request needs to be redirected page ->

      <security:session-management invalid-session-url="/session_timeout.jsp"/>

      ...

   </security:http>

 

       Note that the session timeout redirect page is not required to be certified, otherwise the redirection to the login page will go directly to the user when the session timeout page. Also, if you use this method to detect the overtime session, when you exit the login, and then, without closing the browser and re-login, Spring Security may incorrectly report session has timed out. This is because even if you have Log out, but when you set the session invalid, the corresponding session cookie stored information has not been cleared, so the next request will still be using sessionId previous request. The solution is to delete the definition displayed to the user cookie to save session information corresponding to when logging off.

   <security:http>

      ...

      <! - delete the corresponding session when Log cookie ->

      <security:logout delete-cookies="JSESSIONID"/>

      ...

   </security:http>

       In addition, Spring Security does not guarantee that it is valid for all Servlet container, in the end there is not effective in your container, you need to experiment yourself.

 

1.2     concurrency-control

       Typically, in your application you may only want the same user at the same time, many times only one login is successful log in to your system, usually the corresponding behavior is previous login will enable single sign-on failure, or directly after the first login restrictions. Spring Security of session-management provides us with such restrictions.

       First we need to define as a listener in web.xml.

   <listener>

   <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>

   </listener>

 

       A concurrency-control element is used to limit the user in the same application while allowing the session number has been certified by the presence of at session-management element. The default value is 1, may be specified by max-sessions attribute concurrency-control element.

   <security:http auto-config="true">

      ...

      <security:session-management>

         <security:concurrency-control max-sessions="1"/>

      </security:session-management>

      ...

   </security:http>

 

       When the value has exceeded the max-sessions designated by the number of session authentication, Spring Security default policy of the same user exists is previously set to be invalid. If you want to restrict the user to log in again can set the concurrency-control of error-if-maximum-exceeded the value is true.

 

   <security:http auto-config="true">

      ...

      <security:session-management>

         <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>

      </security:session-management>

      ...

   </security:http>

 

       Setting error-if-maximum-exceeded after is true if you have previously logged in, and then want to log in again, then the system will reject your login, and will be redirected to the specified by the form-login authentication-failure-url. If you log in again by Remember-Me is done, it will not go to the authentication-failure-url, but returns an error code to the 401 unauthorized client, if you still want to redirect a specified page, then you may be specified by session-authentication-error-url attribute session-management, as well as the need to specify the url from Spring Security Administration, which sets its secure = "none" via http elements.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
< security:http  security="none" pattern="/none/**" />
 
< security:http >
 
    < security:form-login />
 
    < security:logout />
 
    < security:intercept-url  pattern="/**" access="ROLE_USER"/>
 
    <!-- session-authentication-error-url必须是不受Spring Security管理的 -->
 
    < security:session-management  session-authentication-error-url="/none/session_authentication_error.jsp">
 
       < security:concurrency-control  max-sessions="1" error-if-maximum-exceeded="true"/>
 
    </ security:session-management >
 
    < security:remember-me  data-source-ref="dataSource"/>
 
</ security:http >

  

       In the above configuration, we configure the session-authentication-error-url is "/none/session_authentication_error.jsp", we through <security: http security = "none" pattern = "/ none / **" /> to specify "/ none" all URL beginning of Spring Security are not subject to control, so that when the user after login, will be redirected to the "/none/session_authentication_error.jsp" when automatic log in again by Remember-Me.

       In the above configuration, why do we need <security: http security = "none" pattern = "/ none / **" /> specify our session-authentication-error-url from Spring Security to control it? Put it into <security: intercept-url pattern = "/ none / **" access = "IS_AUTHENTICATED_ANONYMOUSLY" /> not do it? This difference between both of them before it comes to the introduction of the. The former said they did not use any Spring Security filter, while the latter is naturally do not need to be filtered through the Spring Security authentication, Spring Security's FilterChain, but its corresponding URL can be accessed anonymously, ie no login can access. When using the latter, REMEMBER_ME_FILTER detects that the user is not logged, and which in turn provides information Remember-Me, which will make REMEMBER_ME_FILTER for automatic logon, then the automatic logon because we limited the same time the same user can only log in once, later will be denied login, this time will be redirected to the session-authentication-error-url, redirect access to session-authentication-error-url, passes REMEMBER_ME_FILTER will automatically log in, thus forming an endless loop. Therefore, session-authentication-error-url should use <security: http security = "none" pattern = "/ none / **" /> Spring Security is not to control, instead of using <security: intercept-url pattern = "

 

       In addition, by expired-url attribute specifies when users try to log in again because it leads to a session when the session timeout to jump to the page. Also note that the URL set that does not require authentication.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
< security:http  auto-config="true">
 
    < security:form-login />
 
    < security:logout />
 
    < security:intercept-url  pattern="/expired.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
 
    < security:intercept-url  pattern="/**" access="ROLE_USER"/>
 
    < security:session-management >
 
       < security:concurrency-control  max-sessions="1" expired-url="/expired.jsp" />
 
    </ security:session-management >
 
</ security:http >

  

1.3 session fixation attack protection

       session固定是指服务器在给客户端创建session后,在该session过期之前,它们都将通过该session进行通信。session 固定攻击是指恶意攻击者先通过访问应用来创建一个session,然后再让其他用户使用相同的session进行登录(比如通过发送一个包含该sessionId参数的链接),待其他用户成功登录后,攻击者利用原来的sessionId访问系统将和原用户获得同样的权限。Spring Security默认是对session固定攻击采取了保护措施的,它会在用户登录的时候重新为其生成一个新的session。如果你的应用不需要这种保护或者该保护措施与你的某些需求相冲突,你可以通过session-management的session-fixation-protection属性来改变其保护策略。该属性的可选值有如下三个。

l  migrateSession:这是默认值。其表示在用户登录后将新建一个session,同时将原session中的attribute都copy到新的session中。

l  none:表示继续使用原来的session。

l  newSession:表示重新创建一个新的session,但是不copy原session拥有的attribute。

 

(注:本文是基于Spring Security3.1.6所写)

 

Java设置session超时(失效)的时间

在一般系统登录后,都会设置一个当前session失效的时间,以确保在用户长时间不与服务器交互,自动退出登录,销毁session
具体设置的方法有三种:
1.在web容器中设置(以tomcat为例)
在tomcat-7.0\conf\web.xml中设置,以下是tomcat7.0中默认配置:

1
2
3
<session-config>
<session-timeout> 30 </session-timeout>
</session-config>

tomcat默认session超时时间为30分钟,可以根据需要修改,负数或0为不限制session失效时间

这里要注意这个session设置的时间是根据服务器来计算的,而不是客户端。所以如果在调试程序,应该是修改服务器端时间来测试,而不是客户端

2.在工程的web.xml中设置
<!--时间单位为分钟-->

1
2
3
<session-config>
<session-timeout> 15 </session-timeout>
</session-config>

 这里的15是指15分钟失效

3.通过java代码设置
session.setMaxInactiveInterval(30*60);//以秒为单位,即在没有活动30分钟后,session将失效

三种方式优先等级:1 < 2 < 3

1.1     检测session超时

1.2     concurrency-control

1.3     session 固定攻击保护

 

       Spring Security通过http元素下的子元素session-management提供了对Http Session管理的支持。

 

1.1     检测session超时

       Spring Security可以在用户使用已经超时的sessionId进行请求时将用户引导到指定的页面。这个可以通过如下配置来实现。

   <security:http>

      ...

      <!-- session管理,invalid-session-url指定使用已经超时的sessionId进行请求需要重定向的页面 -->

      <security:session-management invalid-session-url="/session_timeout.jsp"/>

      ...

   </security:http>

 

       需要注意的是session超时的重定向页面应当是不需要认证的,否则再重定向到session超时页面时会直接转到用户登录页面。此外如果你使用这种方式来检测session超时,当你退出了登录,然后在没有关闭浏览器的情况下又重新进行了登录,Spring Security可能会错误的报告session已经超时。这是因为即使你已经退出登录了,但当你设置session无效时,对应保存session信息的cookie并没有被清除,等下次请求时还是会使用之前的sessionId进行请求。解决办法是显示的定义用户在退出登录时删除对应的保存session信息的cookie。

   <security:http>

      ...

      <!-- 退出登录时删除session对应的cookie -->

      <security:logout delete-cookies="JSESSIONID"/>

      ...

   </security:http>

       此外,Spring Security并不保证这对所有的Servlet容器都有效,到底在你的容器上有没有效,需要你自己进行实验。

 

1.2     concurrency-control

       通常情况下,在你的应用中你可能只希望同一用户在同时登录多次时只能有一个是成功登入你的系统的,通常对应的行为是后一次登录将使前一次登录失效,或者直接限制后一次登录。Spring Security的session-management为我们提供了这种限制。

       首先需要我们在web.xml中定义如下监听器。

   <listener>

   <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>

   </listener>

 

       在session-management元素下有一个concurrency-control元素是用来限制同一用户在应用中同时允许存在的已经通过认证的session数量。这个值默认是1,可以通过concurrency-control元素的max-sessions属性来指定。

   <security:http auto-config="true">

      ...

      <security:session-management>

         <security:concurrency-control max-sessions="1"/>

      </security:session-management>

      ...

   </security:http>

 

       当同一用户同时存在的已经通过认证的session数量超过了max-sessions所指定的值时,Spring Security的默认策略是将先前的设为无效。如果要限制用户再次登录可以设置concurrency-control的error-if-maximum-exceeded的值为true。

 

   <security:http auto-config="true">

      ...

      <security:session-management>

         <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>

      </security:session-management>

      ...

   </security:http>

 

       设置error-if-maximum-exceeded为true后如果你之前已经登录了,然后想再次登录,那么系统将会拒绝你的登录,同时将重定向到由form-login指定的authentication-failure-url。如果你的再次登录是通过Remember-Me来完成的,那么将不会转到authentication-failure-url,而是返回未授权的错误码401给客户端,如果你还是想重定向一个指定的页面,那么你可以通过session-management的session-authentication-error-url属性来指定,同时需要指定该url为不受Spring Security管理,即通过http元素设置其secure=”none”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
< security:http  security="none" pattern="/none/**" />
 
< security:http >
 
    < security:form-login />
 
    < security:logout />
 
    < security:intercept-url  pattern="/**" access="ROLE_USER"/>
 
    <!-- session-authentication-error-url必须是不受Spring Security管理的 -->
 
    < security:session-management  session-authentication-error-url="/none/session_authentication_error.jsp">
 
       < security:concurrency-control  max-sessions="1" error-if-maximum-exceeded="true"/>
 
    </ security:session-management >
 
    < security:remember-me  data-source-ref="dataSource"/>
 
</ security:http >

  

       在上述配置中我们配置了session-authentication-error-url为“/none/session_authentication_error.jsp”,同时我们通过<security:http security="none" pattern="/none/**" />指定了以“/none”开始的所有URL都不受Spring Security控制,这样当用户进行登录以后,再次通过Remember-Me进行自动登录时就会重定向到“/none/session_authentication_error.jsp”了。

       在上述配置中为什么我们需要通过<security:http security="none" pattern="/none/**" />指定我们的session-authentication-error-url不受Spring Security控制呢?把它换成<security:intercept-url pattern="/none/**"access="IS_AUTHENTICATED_ANONYMOUSLY"/>不行吗?这就涉及到之前所介绍的它们两者之间的区别了。前者表示不使用任何Spring Security过滤器,自然也就不需要通过Spring Security的认证了,而后者是会被Spring Security的FilterChain进行过滤的,只是其对应的URL可以匿名访问,即不需要登录就可访问。使用后者时,REMEMBER_ME_FILTER检测到用户没有登录,同时其又提供了Remember-Me的相关信息,这将使得REMEMBER_ME_FILTER进行自动登录,那么在自动登录时由于我们限制了同一用户同一时间只能登录一次,后来者将被拒绝登录,这个时候将重定向到session-authentication-error-url,重定向访问session-authentication-error-url时,经过REMEMBER_ME_FILTER时又会自动登录,这样就形成了一个死循环。所以session-authentication-error-url应当使用<security:http security="none" pattern="/none/**" />设置为不受Spring Security控制,而不是使用<security:intercept-url pattern="/none/**"access="IS_AUTHENTICATED_ANONYMOUSLY"/>。

 

       此外,可以通过expired-url属性指定当用户尝试使用一个由于其再次登录导致session超时的session时所要跳转的页面。同时需要注意设置该URL为不需要进行认证。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
< security:http  auto-config="true">
 
    < security:form-login />
 
    < security:logout />
 
    < security:intercept-url  pattern="/expired.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
 
    < security:intercept-url  pattern="/**" access="ROLE_USER"/>
 
    < security:session-management >
 
       < security:concurrency-control  max-sessions="1" expired-url="/expired.jsp" />
 
    </ security:session-management >
 
</ security:http >

  

1.3     session 固定攻击保护

       session固定是指服务器在给客户端创建session后,在该session过期之前,它们都将通过该session进行通信。session 固定攻击是指恶意攻击者先通过访问应用来创建一个session,然后再让其他用户使用相同的session进行登录(比如通过发送一个包含该sessionId参数的链接),待其他用户成功登录后,攻击者利用原来的sessionId访问系统将和原用户获得同样的权限。Spring Security默认是对session固定攻击采取了保护措施的,它会在用户登录的时候重新为其生成一个新的session。如果你的应用不需要这种保护或者该保护措施与你的某些需求相冲突,你可以通过session-management的session-fixation-protection属性来改变其保护策略。该属性的可选值有如下三个。

l  migrateSession:这是默认值。其表示在用户登录后将新建一个session,同时将原session中的attribute都copy到新的session中。

l  none:表示继续使用原来的session。

l  newSession:表示重新创建一个新的session,但是不copy原session拥有的attribute。

 

(注:本文是基于Spring Security3.1.6所写)

 

Java设置session超时(失效)的时间

在一般系统登录后,都会设置一个当前session失效的时间,以确保在用户长时间不与服务器交互,自动退出登录,销毁session
具体设置的方法有三种:
1.在web容器中设置(以tomcat为例)
在tomcat-7.0\conf\web.xml中设置,以下是tomcat7.0中默认配置:

1
2
3
<session-config>
<session-timeout> 30 </session-timeout>
</session-config>

tomcat默认session超时时间为30分钟,可以根据需要修改,负数或0为不限制session失效时间

这里要注意这个session设置的时间是根据服务器来计算的,而不是客户端。所以如果在调试程序,应该是修改服务器端时间来测试,而不是客户端

2.在工程的web.xml中设置
<!--时间单位为分钟-->

1
2
3
<session-config>
<session-timeout> 15 </session-timeout>
</session-config>

 这里的15是指15分钟失效

3.通过java代码设置
session.setMaxInactiveInterval(30*60);//以秒为单位,即在没有活动30分钟后,session将失效

三种方式优先等级:1 < 2 < 3

Guess you like

Origin www.cnblogs.com/zhouyanger/p/12110060.html