From 246c632f3a901bbeb29251c06abaea0422b04151 Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Fri, 30 Aug 2013 12:20:35 -0500 Subject: [PATCH] SEC-2095: Document Servlet API support --- docs/manual/src/docbook/index.xml | 1 + docs/manual/src/docbook/servlet-api.xml | 167 ++++++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 docs/manual/src/docbook/servlet-api.xml diff --git a/docs/manual/src/docbook/index.xml b/docs/manual/src/docbook/index.xml index bb3d56d6c2..191ee1405a 100644 --- a/docs/manual/src/docbook/index.xml +++ b/docs/manual/src/docbook/index.xml @@ -128,6 +128,7 @@ + diff --git a/docs/manual/src/docbook/servlet-api.xml b/docs/manual/src/docbook/servlet-api.xml new file mode 100644 index 0000000000..9f5db6c036 --- /dev/null +++ b/docs/manual/src/docbook/servlet-api.xml @@ -0,0 +1,167 @@ + + + Servlet API integration + + This section describes how Spring Security is integrated with the Servlet API. The + servletapi-xml sample application demonstrates + the usage of each of these methods. +
+ Servlet 2.5+ Integration +
+ HttpServletRequest.getRemoteUser() + The HttpServletRequest.getRemoteUser() + will return the result of SecurityContextHolder.getContext().getAuthentication().getName() which is typically the current + username. This can be useful if you want to display the current username in your application. Additionally, checking if this + is null can be used to indicate if a user has authenticated or is anonymous. Knowing if the user is authenticated or not can + be useful for determining if certain UI elements should be shown or not (i.e. a log out link should only be displayed if the + user is authenticated). +
+
+ HttpServletRequest.getUserPrincipal() + The HttpServletRequest.getUserPrincipal() + will return the result of SecurityContextHolder.getContext().getAuthentication(). This means it is an Authentication + which is typically an instance of UsernamePasswordAuthenticationToken when using username and password based authentication. This can be useful if + you need additional information about your user. For example, you might have created a custom UserDetailsService + that returns a custom UserDetails containing a first and last name for your user. You could obtain this information with the + following: + + + It should be noted that it is typically bad practice to perform so much logic throughout your application. Instead, one should centralize it to reduce + any coupling of Spring Security and the Servlet API's. + + +
+
+ HttpServletRequest.isUserInRole(String) + The HttpServletRequest.isUserInRole(String) + will determine if SecurityContextHolder.getContext().getAuthentication().getAuthorities() contains a + GrantedAuthority with the role passed into isUserInRole(String). Typically users should not pass in the "ROLE_" prefix + into this method since it is added automatically. For example, if you want to determine if the current user has the authority "ROLE_ADMIN", you could use the + the following: + + This might be useful to determine if certain UI components should be displayed. For example, you might display admin links only if the current + user is an admin. +
+
+
+ Servlet 3+ Integration + The following section describes the Servlet 3 methods that Spring Security integrates with. +
+ HttpServletRequest.authenticate(HttpServletRequest,HttpServletResponse) + The HttpServletRequest.authenticate(HttpServletRequest,HttpServletResponse) + method can be used to ensure that a user is authenticated. If they are not authenticated, the configured AuthenticationEntryPoint will be used to request the user to authenticate + (i.e. redirect to the login page). +
+
+ HttpServletRequest.login(String,String) + The HttpServletRequest.login(String,String) + method can be used to authenticate the user with the current AuthenticationManager. For example, the following would attempt to + authenticate with the username "user" and password "password": + + + It is not necessary to catch the ServletException if you want Spring Security to process the failed authentication attempt. + +
+
+ HttpServletRequest.logout() + The HttpServletRequest.logout() + method can be used to log the current user out. + Typically this means that the SecurityContextHolder will be cleared out, the HttpSession will be invalidated, any "Remember Me" authentication will be + cleaned up, etc. However, the configured LogoutHandler implementations will vary depending on your Spring Security configuration. It is important to note + that after HttpServletRequest.logout() has been invoked, you are still in charge of writing a response out. Typically this would involve a redirect to the + welcome page. +
+
+ AsyncContext.start(Runnable) + The AsynchContext.start(Runnable) + method that ensures your credentials will be propagated to the new Thread. Using Spring Security's concurrency support, Spring Security overrides + the AsyncContext.start(Runnable) to ensure that the current SecurityContext is used when processing the Runnable. For example, the following + would output the current user's Authentication: + +
+
+ Async Servlet Support + If you are using Java Based configuration, you are ready to go. If you are using XML configuration, there are + a few updates that are necessary. The first step is to ensure you have updated your web.xml to use at least the 3.0 schema + as shown below: + + +]]> + Next you need to ensure that your springSecurityFilterChain is setup for processing asynchronous requests. + + springSecurityFilterChain + + org.springframework.web.filter.DelegatingFilterProxy + + true + + + springSecurityFilterChain + /* + REQUEST + ASYNC +]]> + That's it! Now Spring Security will ensure that your SecurityContext is propagated on asynchronous requests too. + So how does it work? If you are not really interested, feel free to skip the remainder of this section, otherwise read on. Most of this + is built into the Servlet specification, but there is a little bit of tweaking that Spring Security does to ensure things work with + asynchronous requests properly. Prior to Spring Security 3.2, the SecurityContext from the SecurityContextHolder was automatically saved as soon + as the HttpServletResponse was committed. This can cause issues in a Async environment. For example, consider the following: + + The issue is that this Thread is not known to Spring Security, so the SecurityContext is not propagated to it. This means when we commit the + HttpServletResponse there is no SecuriytContext. When Spring Security automatically saved the SecurityContext on committing the HttpServletResponse it + would lose our logged in user. + Since version 3.2, Spring Security is smart enough to no longer automatically save the SecurityContext on commiting the HttpServletResponse + as soon as HttpServletRequest.startAsync() is invoked. +
+
+
+ Servlet 3.1+ Integration + The following section describes the Servlet 3.1 methods that Spring Security integrates with. +
+ HttpServletRequest#changeSessionId() + The HttpServletRequest.changeSessionId() + is the default method for protecting against Session Fixation attacks in Servlet 3.1 and higher. +
+
+