Run form-based acegitest2demo. Do you find anything inappropriate? The test error is as follows: 1. run http: // localhost: 8080/acegitest2/userinfo in IE. jsp 2. it will definitely go to the login page, and then log in to test/1 To Go To The accessdefined no-Permission page. Use lisi/1 to enter the current user information.
However, if you log in with test/1 and run http: // localhost: 8080/acegitest2/userinfo. jsp again, you can guess what will happen? Haha, go to the accessdefined no permission page. I open ie again, run this url, or enter the page without permission. Is it cache? So I am a new browser, not a new tag? No matter how many layers of IE browser you open, look at F12 and you will find that token and sessionId are the same.
What problems does this mean? This indicates that the IE browser you use is session sharing, which is specially set for the convenience of users by the browser. By default, sessions are shared in IE8.
So how to create a page with different sessions? In IE, file-create a session. Modify the shortcut properties of the browser. Under the C: \ Program Files \ Internet Explorer folder, use iexplore.exe to create a shortcut to the desktop. Right-click the shortcut on the desktop and choose Properties, modify "target" to "C: \ Program Files \ Internet Explorer \ iexplore.exe"-nomerge browsers started using this shortcut will not share sessions in the above way, change it, and then run the url, go to the "no permission" Page and find that it has nothing to do with the session. [We will talk about the blog post related to the session later]. You use 360 and Google to test the same page. Debug ...... [When debugging, a method was missing, leading to session errors.] Because the filters used to configure acegi are authenticationProcessingFilter, exceptionTranslationFilter, and filterInvocationInterceptor, the first one is identity authentication. debug first enters the first filter, but actually enters the AbstractProcessingFilter, while authenticationProcessingFilter is the extends AbstractProcessingFilter, where the first filter method:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (!(request instanceof HttpServletRequest)) { throw new ServletException( "Can only process HttpServletRequest"); } if (!(response instanceof HttpServletResponse)) { throw new ServletException( "Can only process HttpServletResponse"); } HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; if (requiresAuthentication(httpRequest, httpResponse)) { if ( logger.isDebugEnabled()) { logger.debug( "Request is to process authentication"); } Authentication authResult; try { onPreAuthentication(httpRequest, httpResponse); authResult = attemptAuthentication(httpRequest); } catch (AuthenticationException failed) { // Authentication failed unsuccessfulAuthentication(httpRequest, httpResponse, failed); return; } // Authentication success if ( continueChainBeforeSuccessfulAuthentication) { chain.doFilter(request, response); } successfulAuthentication(httpRequest, httpResponse, authResult); return; } chain.doFilter(request, response); }
The pivot of this method is: requiresAuthentication (httpRequest, httpResponse). You can guess whether the verification is required based on the name. If this parameter is set to true during the first running, authentication is performed. However, when the second execution is performed, it is false and jumps directly to the next filter. Predictionfilter: capture errors. Then go to the authorized filter-filterInvocationInterceptor to obtain SecurityContextHolder. getContext (). getAuthentication (). securitycontex has a permission object and then directly enters the decide voting method. So the key question is, why does securitycontext retain the last permission object? After the first fiter authentication, securitycontext saves the authenticated objects to successfulAuthentication and SecurityContextHolder. getContext (). setAuthentication (authResult). The key code in filterInvocationInterceptor is as follows:
if (!SecurityContextHolder.getContext().getAuthentication().isAuthenticated() || alwaysReauthenticate) { try { authenticated = this. authenticationManager.authenticate(SecurityContextHolder. getContext() .getAuthentication()); } catch (AuthenticationException authenticationException) { throw authenticationException; } // We don't authenticated.setAuthentication(true), because each // provider should do that if ( logger.isDebugEnabled()) { logger.debug( "Successfully Authenticated: " + authenticated.toString()); } SecurityContextHolder. getContext().setAuthentication(authenticated); } else { authenticated = SecurityContextHolder.getContext().getAuthentication(); if ( logger.isDebugEnabled()) { logger.debug( "Previously Authenticated: " + authenticated.toString()); } }
Directly obtain the permission object and perform voting matching.
This blog mainly analyzes the key code of form authentication. In the next blog, let's see what changes will happen if sessionfilter is added?