324.c41411db.js 12.5 KB
Newer Older
茶陵後's avatar
茶陵後 已提交
1
(window.webpackJsonp=window.webpackJsonp||[]).push([[324],{750:function(e,t,s){"use strict";s.r(t);var n=s(56),i=Object(n.a)({},(function(){var e=this,t=e.$createElement,s=e._self._c||t;return s("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[s("h1",{attrs:{id:"spring-session-find-by-username"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#spring-session-find-by-username"}},[e._v("#")]),e._v(" Spring Session - find by username")]),e._v(" "),s("p",[e._v("This guide describes how to use Spring Session to find sessions by username.")]),e._v(" "),s("table",[s("thead",[s("tr",[s("th"),e._v(" "),s("th",[e._v("You can find the completed guide in the "),s("a",{attrs:{href:"#findbyusername-sample"}},[e._v("findbyusername application")]),e._v(".")])])]),e._v(" "),s("tbody")]),e._v(" "),s("p",[s("RouterLink",{attrs:{to:"/en/spring-session/index.html"}},[e._v("Index")])],1),e._v(" "),s("h2",{attrs:{id:"assumptions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#assumptions"}},[e._v("#")]),e._v(" Assumptions")]),e._v(" "),s("p",[e._v("The guide assumes you have already added Spring Session to your application by using the built-in Redis configuration support.\nThe guide also assumes you have already applied Spring Security to your application.\nHowever, we the guide is somewhat general purpose and can be applied to any technology with minimal changes, which we discuss later in the guide.")]),e._v(" "),s("table",[s("thead",[s("tr",[s("th"),e._v(" "),s("th",[e._v("If you need to learn how to add Spring Session to your project, see the listing of "),s("RouterLink",{attrs:{to:"/en/spring-session/#samples"}},[e._v("samples and guides")])],1)])]),e._v(" "),s("tbody")]),e._v(" "),s("h2",{attrs:{id:"about-the-sample"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#about-the-sample"}},[e._v("#")]),e._v(" About the Sample")]),e._v(" "),s("p",[e._v("Our sample uses this feature to invalidate the users session that might have been compromised.\nConsider the following scenario:")]),e._v(" "),s("ul",[s("li",[s("p",[e._v("User goes to library and authenticates to the application.")])]),e._v(" "),s("li",[s("p",[e._v("User goes home and realizes they forgot to log out.")])]),e._v(" "),s("li",[s("p",[e._v("User can log in and end the session from the library using clues like the location, created time, last accessed time, and so on.")])])]),e._v(" "),s("p",[e._v("Would it not be nice if we could let the user invalidate the session at the library from any device with which they authenticate?\nThis sample demonstrates how this is possible.")]),e._v(" "),s("h2",{attrs:{id:"using-findbyindexnamesessionrepository"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#using-findbyindexnamesessionrepository"}},[e._v("#")]),e._v(" Using "),s("code",[e._v("FindByIndexNameSessionRepository")])]),e._v(" "),s("p",[e._v("To look up a user by their username, you must first choose a "),s("code",[e._v("SessionRepository")]),e._v(" that implements "),s("RouterLink",{attrs:{to:"/en/spring-session/#api-findbyindexnamesessionrepository"}},[s("code",[e._v("FindByIndexNameSessionRepository")])]),e._v(".\nOur sample application assumes that the Redis support is already set up, so we are ready to go.")],1),e._v(" "),s("h2",{attrs:{id:"mapping-the-user-name"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mapping-the-user-name"}},[e._v("#")]),e._v(" Mapping the User Name")]),e._v(" "),s("p",[s("code",[e._v("FindByIndexNameSessionRepository")]),e._v(" can find a session only by the user name if the developer instructs Spring Session what user is associated with the "),s("code",[e._v("Session")]),e._v(".\nYou can do so by ensuring that the session attribute with the name "),s("code",[e._v("FindByUsernameSessionRepository.PRINCIPAL_NAME_INDEX_NAME")]),e._v(" is populated with the username.")]),e._v(" "),s("p",[e._v("Generally speaking, you can do so with the following code immediately after the user authenticates:")]),e._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v('String username = "username";\nthis.session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, username);\n')])])]),s("h2",{attrs:{id:"mapping-the-user-name-with-spring-security"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mapping-the-user-name-with-spring-security"}},[e._v("#")]),e._v(" Mapping the User Name with Spring Security")]),e._v(" "),s("p",[e._v("Since we use Spring Security, the user name is automatically indexed for us.\nThis means we need not perform any steps to ensure the user name is indexed.")]),e._v(" "),s("h2",{attrs:{id:"adding-additional-data-to-the-session"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#adding-additional-data-to-the-session"}},[e._v("#")]),e._v(" Adding Additional Data to the Session")]),e._v(" "),s("p",[e._v("It may be nice to associate additional information (such as the IP Address, the browser, location, and other details) to the session.\nDoing so makes it easier for the user to know which session they are looking at.")]),e._v(" "),s("p",[e._v("To do so, determine which session attribute you want to use and what information you wish to provide.\nThen create a Java bean that is added as a session attribute.\nFor example, our sample application includes the location and access type of the session, as the following listing shows:")]),e._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v("public class SessionDetails implements Serializable {\n\n\tprivate String location;\n\n\tprivate String accessType;\n\n\tpublic String getLocation() {\n\t\treturn this.location;\n\t}\n\n\tpublic void setLocation(String location) {\n\t\tthis.location = location;\n\t}\n\n\tpublic String getAccessType() {\n\t\treturn this.accessType;\n\t}\n\n\tpublic void setAccessType(String accessType) {\n\t\tthis.accessType = accessType;\n\t}\n\n\tprivate static final long serialVersionUID = 8850489178248613501L;\n\n}\n")])])]),s("p",[e._v("We then inject that information into the session on each HTTP request using a "),s("code",[e._v("SessionDetailsFilter")]),e._v(", as the following example shows:")]),e._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v('@Override\npublic void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)\n\t\tthrows IOException, ServletException {\n\tchain.doFilter(request, response);\n\n\tHttpSession session = request.getSession(false);\n\tif (session != null) {\n\t\tString remoteAddr = getRemoteAddress(request);\n\t\tString geoLocation = getGeoLocation(remoteAddr);\n\n\t\tSessionDetails details = new SessionDetails();\n\t\tdetails.setAccessType(request.getHeader("User-Agent"));\n\t\tdetails.setLocation(remoteAddr + " " + geoLocation);\n\n\t\tsession.setAttribute("SESSION_DETAILS", details);\n\t}\n}\n')])])]),s("p",[e._v("We obtain the information we want and then set the "),s("code",[e._v("SessionDetails")]),e._v(" as an attribute in the "),s("code",[e._v("Session")]),e._v(".\nWhen we retrieve the "),s("code",[e._v("Session")]),e._v(" by user name, we can then use the session to access our "),s("code",[e._v("SessionDetails")]),e._v(" as we would any other session attribute.")]),e._v(" "),s("table",[s("thead",[s("tr",[s("th"),e._v(" "),s("th",[e._v("You might wonder why Spring Session does not provide "),s("code",[e._v("SessionDetails")]),e._v(" functionality out of the box."),s("br"),e._v("We have two reasons."),s("br"),e._v("The first reason is that it is very trivial for applications to implement this themselves."),s("br"),e._v("The second reason is that the information that is populated in the session (and how frequently that information is updated) is highly application-dependent.")])])]),e._v(" "),s("tbody")]),e._v(" "),s("h2",{attrs:{id:"finding-sessions-for-a-specific-user"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#finding-sessions-for-a-specific-user"}},[e._v("#")]),e._v(" Finding sessions for a specific user")]),e._v(" "),s("p",[e._v("We can now find all the sessions for a specific user.\nThe following example shows how to do so:")]),e._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v('@Autowired\nFindByIndexNameSessionRepository<? extends Session> sessions;\n\n@RequestMapping("/")\npublic String index(Principal principal, Model model) {\n\tCollection<? extends Session> usersSessions = this.sessions.findByPrincipalName(principal.getName()).values();\n\tmodel.addAttribute("sessions", usersSessions);\n\treturn "index";\n}\n')])])]),s("p",[e._v("In our instance, we find all sessions for the currently logged in user.\nHowever, you can modify this for an administrator to use a form to specify which user to look up.")]),e._v(" "),s("h2",{attrs:{id:"findbyusername-sample-application"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#findbyusername-sample-application"}},[e._v("#")]),e._v(" "),s("code",[e._v("findbyusername")]),e._v(" Sample Application")]),e._v(" "),s("p",[e._v("This section describes how to use the "),s("code",[e._v("findbyusername")]),e._v(" sample application.")]),e._v(" "),s("h3",{attrs:{id:"running-the-findbyusername-sample-application"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#running-the-findbyusername-sample-application"}},[e._v("#")]),e._v(" Running the "),s("code",[e._v("findbyusername")]),e._v(" Sample Application")]),e._v(" "),s("p",[e._v("You can run the sample by obtaining the "),s("a",{attrs:{href:"https://github.com/spring-projects/spring-session/archive/main.zip",target:"_blank",rel:"noopener noreferrer"}},[e._v("source code"),s("OutboundLink")],1),e._v(" and invoking the following command:")]),e._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v("$ ./gradlew :spring-session-sample-boot-findbyusername:bootRun\n")])])]),s("table",[s("thead",[s("tr",[s("th"),e._v(" "),s("th",[e._v("For the sample to work, you must "),s("a",{attrs:{href:"https://redis.io/download",target:"_blank",rel:"noopener noreferrer"}},[e._v("install Redis 2.8+"),s("OutboundLink")],1),e._v(" on localhost and run it with the default port (6379)."),s("br"),e._v("Alternatively, you can update the "),s("code",[e._v("RedisConnectionFactory")]),e._v(" to point to a Redis server."),s("br"),e._v("Another option is to use "),s("a",{attrs:{href:"https://www.docker.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Docker"),s("OutboundLink")],1),e._v(" to run Redis on localhost."),s("br"),e._v("See "),s("a",{attrs:{href:"https://hub.docker.com/_/redis/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Docker Redis repository"),s("OutboundLink")],1),e._v(" for detailed instructions.")])])]),e._v(" "),s("tbody")]),e._v(" "),s("p",[e._v("You should now be able to access the application at "),s("a",{attrs:{href:"http://localhost:8080/",target:"_blank",rel:"noopener noreferrer"}},[e._v("http://localhost:8080/"),s("OutboundLink")],1)]),e._v(" "),s("h3",{attrs:{id:"exploring-the-security-sample-application"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#exploring-the-security-sample-application"}},[e._v("#")]),e._v(" Exploring the security Sample Application")]),e._v(" "),s("p",[e._v("You can now try using the application. Enter the following to log in:")]),e._v(" "),s("ul",[s("li",[s("p",[s("strong",[e._v("Username")]),e._v(" "),s("em",[e._v("user")])])]),e._v(" "),s("li",[s("p",[s("strong",[e._v("Password")]),e._v(" "),s("em",[e._v("password")])])])]),e._v(" "),s("p",[e._v("Now click the "),s("strong",[e._v("Login")]),e._v(" button.\nYou should now see a message indicating your are logged in with the user entered previously.\nYou should also see a listing of active sessions for the currently logged in user.")]),e._v(" "),s("p",[e._v("You can emulate the flow we discussed in the "),s("a",{attrs:{href:"#_about_the_sample"}},[e._v("About the Sample")]),e._v(" section by doing the following:")]),e._v(" "),s("ul",[s("li",[s("p",[e._v("Open a new incognito window and navigate to "),s("a",{attrs:{href:"http://localhost:8080/",target:"_blank",rel:"noopener noreferrer"}},[e._v("http://localhost:8080/"),s("OutboundLink")],1)])]),e._v(" "),s("li",[s("p",[e._v("Enter the following to log in:")]),e._v(" "),s("ul",[s("li",[s("p",[s("strong",[e._v("Username")]),e._v(" "),s("em",[e._v("user")])])]),e._v(" "),s("li",[s("p",[s("strong",[e._v("Password")]),e._v(" "),s("em",[e._v("password")])])])])]),e._v(" "),s("li",[s("p",[e._v("End your original session.")])]),e._v(" "),s("li",[s("p",[e._v("Refresh the original window and see that you are logged out.")])])])])}),[],!1,null,null,null);t.default=i.exports}}]);