(window.webpackJsonp=window.webpackJsonp||[]).push([[233],{659:function(e,t,o){"use strict";o.r(t);var r=o(56),n=Object(r.a)({},(function(){var e=this,t=e.$createElement,o=e._self._c||t;return o("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[o("h1",{attrs:{id:"handling-logouts"}},[o("a",{staticClass:"header-anchor",attrs:{href:"#handling-logouts"}},[e._v("#")]),e._v(" Handling Logouts")]),e._v(" "),o("h2",{attrs:{id:"logout-java-kotlin-configuration"}},[o("a",{staticClass:"header-anchor",attrs:{href:"#logout-java-kotlin-configuration"}},[e._v("#")]),e._v(" Logout Java/Kotlin Configuration")]),e._v(" "),o("p",[e._v("When using the "),o("code",[e._v("[WebSecurityConfigurerAdapter](https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.html)")]),e._v(", logout capabilities are automatically applied.\nThe default is that accessing the URL "),o("code",[e._v("/logout")]),e._v(" will log the user out by:")]),e._v(" "),o("ul",[o("li",[o("p",[e._v("Invalidating the HTTP Session")])]),e._v(" "),o("li",[o("p",[e._v("Cleaning up any RememberMe authentication that was configured")])]),e._v(" "),o("li",[o("p",[e._v("Clearing the "),o("code",[e._v("SecurityContextHolder")])])]),e._v(" "),o("li",[o("p",[e._v("Redirect to "),o("code",[e._v("/login?logout")])])])]),e._v(" "),o("p",[e._v("Similar to configuring login capabilities, however, you also have various options to further customize your logout requirements:")]),e._v(" "),o("p",[e._v("Example 1. Logout Configuration")]),e._v(" "),o("p",[e._v("Java")]),e._v(" "),o("div",{staticClass:"language- extra-class"},[o("pre",{pre:!0,attrs:{class:"language-text"}},[o("code",[e._v('protected void configure(HttpSecurity http) throws Exception {\n http\n .logout(logout -> logout (1)\n .logoutUrl("/my/logout") (2)\n .logoutSuccessUrl("/my/index") (3)\n .logoutSuccessHandler(logoutSuccessHandler) (4)\n .invalidateHttpSession(true) (5)\n .addLogoutHandler(logoutHandler) (6)\n .deleteCookies(cookieNamesToClear) (7)\n )\n ...\n}\n')])])]),o("p",[e._v("Kotlin")]),e._v(" "),o("div",{staticClass:"language- extra-class"},[o("pre",{pre:!0,attrs:{class:"language-text"}},[o("code",[e._v('override fun configure(http: HttpSecurity) {\n http {\n logout {\n logoutUrl = "/my/logout" (1)\n logoutSuccessUrl = "/my/index" (2)\n logoutSuccessHandler = customLogoutSuccessHandler (3)\n invalidateHttpSession = true (4)\n addLogoutHandler(logoutHandler) (5)\n deleteCookies(cookieNamesToClear) (6)\n }\n }\n}\n')])])]),o("table",[o("thead",[o("tr",[o("th",[o("strong",[e._v("1")])]),e._v(" "),o("th",[e._v("Provides logout support."),o("br"),e._v("This is automatically applied when using "),o("code",[e._v("WebSecurityConfigurerAdapter")]),e._v(".")])])]),e._v(" "),o("tbody",[o("tr",[o("td",[o("strong",[e._v("2")])]),e._v(" "),o("td",[e._v("The URL that triggers log out to occur (default is "),o("code",[e._v("/logout")]),e._v(")."),o("br"),e._v("If CSRF protection is enabled (default), then the request must also be a POST."),o("br"),e._v("For more information, please consult the "),o("a",{attrs:{href:"https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#logoutUrl-java.lang.String-",target:"_blank",rel:"noopener noreferrer"}},[e._v("Javadoc"),o("OutboundLink")],1),e._v(".")])]),e._v(" "),o("tr",[o("td",[o("strong",[e._v("3")])]),e._v(" "),o("td",[e._v("The URL to redirect to after logout has occurred."),o("br"),e._v("The default is "),o("code",[e._v("/login?logout")]),e._v("."),o("br"),e._v("For more information, please consult the "),o("a",{attrs:{href:"https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#logoutSuccessUrl-java.lang.String-",target:"_blank",rel:"noopener noreferrer"}},[e._v("Javadoc"),o("OutboundLink")],1),e._v(".")])]),e._v(" "),o("tr",[o("td",[o("strong",[e._v("4")])]),e._v(" "),o("td",[e._v("Let’s you specify a custom "),o("code",[e._v("LogoutSuccessHandler")]),e._v("."),o("br"),e._v("If this is specified, "),o("code",[e._v("logoutSuccessUrl()")]),e._v(" is ignored."),o("br"),e._v("For more information, please consult the "),o("a",{attrs:{href:"https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#logoutSuccessHandler-org.springframework.security.web.authentication.logout.LogoutSuccessHandler-",target:"_blank",rel:"noopener noreferrer"}},[e._v("Javadoc"),o("OutboundLink")],1),e._v(".")])]),e._v(" "),o("tr",[o("td",[o("strong",[e._v("5")])]),e._v(" "),o("td",[e._v("Specify whether to invalidate the "),o("code",[e._v("HttpSession")]),e._v(" at the time of logout."),o("br"),e._v("This is "),o("strong",[e._v("true")]),e._v(" by default."),o("br"),e._v("Configures the "),o("code",[e._v("SecurityContextLogoutHandler")]),e._v(" under the covers."),o("br"),e._v("For more information, please consult the "),o("a",{attrs:{href:"https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html#invalidateHttpSession-boolean-",target:"_blank",rel:"noopener noreferrer"}},[e._v("Javadoc"),o("OutboundLink")],1),e._v(".")])]),e._v(" "),o("tr",[o("td",[o("strong",[e._v("6")])]),e._v(" "),o("td",[e._v("Adds a "),o("code",[e._v("LogoutHandler")]),e._v("."),o("code",[e._v("SecurityContextLogoutHandler")]),e._v(" is added as the last "),o("code",[e._v("LogoutHandler")]),e._v(" by default.")])]),e._v(" "),o("tr",[o("td",[o("strong",[e._v("7")])]),e._v(" "),o("td",[e._v("Allows specifying the names of cookies to be removed on logout success."),o("br"),e._v("This is a shortcut for adding a "),o("code",[e._v("CookieClearingLogoutHandler")]),e._v(" explicitly.")])])])]),e._v(" "),o("table",[o("thead",[o("tr",[o("th"),e._v(" "),o("th",[e._v("Logouts can of course also be configured using the XML Namespace notation."),o("br"),e._v("Please see the documentation for the "),o("RouterLink",{attrs:{to:"/en/appendix/namespace/http.html#nsa-logout"}},[e._v(" logout element")]),e._v(" in the Spring Security XML Namespace section for further details.")],1)])]),e._v(" "),o("tbody")]),e._v(" "),o("p",[e._v("Generally, in order to customize logout functionality, you can add"),o("code",[e._v("[LogoutHandler](https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/web/authentication/logout/LogoutHandler.html)")]),e._v("and/or"),o("code",[e._v("[LogoutSuccessHandler](https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/web/authentication/logout/LogoutSuccessHandler.html)")]),e._v("implementations.\nFor many common scenarios, these handlers are applied under the\ncovers when using the fluent API.")]),e._v(" "),o("h2",{attrs:{id:"logout-xml-configuration"}},[o("a",{staticClass:"header-anchor",attrs:{href:"#logout-xml-configuration"}},[e._v("#")]),e._v(" Logout XML Configuration")]),e._v(" "),o("p",[e._v("The "),o("code",[e._v("logout")]),e._v(" element adds support for logging out by navigating to a particular URL.\nThe default logout URL is "),o("code",[e._v("/logout")]),e._v(", but you can set it to something else using the "),o("code",[e._v("logout-url")]),e._v(" attribute.\nMore information on other available attributes may be found in the namespace appendix.")]),e._v(" "),o("h2",{attrs:{id:"logouthandler"}},[o("a",{staticClass:"header-anchor",attrs:{href:"#logouthandler"}},[e._v("#")]),e._v(" LogoutHandler")]),e._v(" "),o("p",[e._v("Generally, "),o("code",[e._v("[LogoutHandler](https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/web/authentication/logout/LogoutHandler.html)")]),e._v("implementations indicate classes that are able to participate in logout handling.\nThey are expected to be invoked to perform necessary clean-up.\nAs such they should\nnot throw exceptions.\nVarious implementations are provided:")]),e._v(" "),o("ul",[o("li",[o("p",[o("a",{attrs:{href:"https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/web/authentication/rememberme/PersistentTokenBasedRememberMeServices.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("PersistentTokenBasedRememberMeServices"),o("OutboundLink")],1)])]),e._v(" "),o("li",[o("p",[o("a",{attrs:{href:"https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/web/authentication/rememberme/TokenBasedRememberMeServices.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("TokenBasedRememberMeServices"),o("OutboundLink")],1)])]),e._v(" "),o("li",[o("p",[o("a",{attrs:{href:"https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/web/authentication/logout/CookieClearingLogoutHandler.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("CookieClearingLogoutHandler"),o("OutboundLink")],1)])]),e._v(" "),o("li",[o("p",[o("a",{attrs:{href:"https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/web/csrf/CsrfLogoutHandler.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("CsrfLogoutHandler"),o("OutboundLink")],1)])]),e._v(" "),o("li",[o("p",[o("a",{attrs:{href:"https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/web/authentication/logout/SecurityContextLogoutHandler.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("SecurityContextLogoutHandler"),o("OutboundLink")],1)])]),e._v(" "),o("li",[o("p",[o("a",{attrs:{href:"https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/web/authentication/logout/HeaderWriterLogoutHandler.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("HeaderWriterLogoutHandler"),o("OutboundLink")],1)])])]),e._v(" "),o("p",[e._v("Please see "),o("RouterLink",{attrs:{to:"/en/spring-security/rememberme.html#remember-me-impls"}},[e._v("Remember-Me Interfaces and Implementations")]),e._v(" for details.")],1),e._v(" "),o("p",[e._v("Instead of providing "),o("code",[e._v("LogoutHandler")]),e._v(" implementations directly, the fluent API also provides shortcuts that provide the respective "),o("code",[e._v("LogoutHandler")]),e._v(" implementations under the covers.\nE.g. "),o("code",[e._v("deleteCookies()")]),e._v(" allows specifying the names of one or more cookies to be removed on logout success.\nThis is a shortcut compared to adding a "),o("code",[e._v("CookieClearingLogoutHandler")]),e._v(".")]),e._v(" "),o("h2",{attrs:{id:"logoutsuccesshandler"}},[o("a",{staticClass:"header-anchor",attrs:{href:"#logoutsuccesshandler"}},[e._v("#")]),e._v(" LogoutSuccessHandler")]),e._v(" "),o("p",[e._v("The "),o("code",[e._v("LogoutSuccessHandler")]),e._v(" is called after a successful logout by the "),o("code",[e._v("LogoutFilter")]),e._v(", to handle e.g.\nredirection or forwarding to the appropriate destination.\nNote that the interface is almost the same as the "),o("code",[e._v("LogoutHandler")]),e._v(" but may raise an exception.")]),e._v(" "),o("p",[e._v("The following implementations are provided:")]),e._v(" "),o("ul",[o("li",[o("p",[o("a",{attrs:{href:"https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/web/authentication/logout/SimpleUrlLogoutSuccessHandler.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("SimpleUrlLogoutSuccessHandler"),o("OutboundLink")],1)])]),e._v(" "),o("li",[o("p",[e._v("HttpStatusReturningLogoutSuccessHandler")])])]),e._v(" "),o("p",[e._v("As mentioned above, you don’t need to specify the "),o("code",[e._v("SimpleUrlLogoutSuccessHandler")]),e._v(" directly.\nInstead, the fluent API provides a shortcut by setting the "),o("code",[e._v("logoutSuccessUrl()")]),e._v(".\nThis will setup the "),o("code",[e._v("SimpleUrlLogoutSuccessHandler")]),e._v(" under the covers.\nThe provided URL will be redirected to after a logout has occurred.\nThe default is "),o("code",[e._v("/login?logout")]),e._v(".")]),e._v(" "),o("p",[e._v("The "),o("code",[e._v("HttpStatusReturningLogoutSuccessHandler")]),e._v(" can be interesting in REST API type scenarios.\nInstead of redirecting to a URL upon the successful logout, this "),o("code",[e._v("LogoutSuccessHandler")]),e._v(" allows you to provide a plain HTTP status code to be returned.\nIf not configured a status code 200 will be returned by default.")]),e._v(" "),o("h2",{attrs:{id:"further-logout-related-references"}},[o("a",{staticClass:"header-anchor",attrs:{href:"#further-logout-related-references"}},[e._v("#")]),e._v(" Further Logout-Related References")]),e._v(" "),o("ul",[o("li",[o("p",[o("a",{attrs:{href:"#ns-logout"}},[e._v("Logout Handling")])])]),e._v(" "),o("li",[o("p",[o("RouterLink",{attrs:{to:"/en/test/mockmvc/logout.html#test-logout"}},[e._v(" Testing Logout")])],1)]),e._v(" "),o("li",[o("p",[o("RouterLink",{attrs:{to:"/en/integrations/servlet-api.html#servletapi-logout"}},[e._v(" HttpServletRequest.logout()")])],1)]),e._v(" "),o("li",[o("p",[o("RouterLink",{attrs:{to:"/en/spring-security/rememberme.html#remember-me-impls"}},[e._v("Remember-Me Interfaces and Implementations")])],1)]),e._v(" "),o("li",[o("p",[o("RouterLink",{attrs:{to:"/en/exploits/csrf.html#servlet-considerations-csrf-logout"}},[e._v(" Logging Out")]),e._v(" in section CSRF Caveats")],1)]),e._v(" "),o("li",[o("p",[e._v("Section "),o("RouterLink",{attrs:{to:"/en/spring-security/cas.html#cas-singlelogout"}},[e._v(" Single Logout")]),e._v(" (CAS protocol)")],1)]),e._v(" "),o("li",[o("p",[e._v("Documentation for the "),o("RouterLink",{attrs:{to:"/en/appendix/namespace/http.html#nsa-logout"}},[e._v(" logout element")]),e._v(" in the Spring Security XML Namespace section")],1)])]),e._v(" "),o("p",[o("RouterLink",{attrs:{to:"/en/spring-security/runas.html"}},[e._v("Run-As")]),o("RouterLink",{attrs:{to:"/en/spring-security/events.html"}},[e._v("Authentication Events")])],1)])}),[],!1,null,null,null);t.default=n.exports}}]);