This article turns to self-blog, reprint please declare address: http://www.heartlifes.com/archives/7/ background:
1. The project uses Yale's CAs for single sign-on. 2. Using the Spring-oauth package to implement OAUTH2 Services 3. Use Spring-cas to do spring-security and CAS integration phenomena:
Development reported a bug, the approximate process is the system call/oauth/authorize interface, was spring-security interception into the CAs login interface, the user entered the user name password to do the login, login success, the browser jump to the authorization interface, At this time the user points the fallback button (the user is so bored), entered the 404 error interface reason:
After a spring of the source found, Spring-security's default interceptor stack, there is an interceptor called Requestcacheawarefilter Official document explains that this interceptor is used to restore the user interface interrupted by the login operation Jump Switch, what does it mean? , that is to say: 1. The login method provided by your system with Spring-security 2. The user points to a link of your system xxx, this xxx in spring-security is a need to be safe to control the connection 3. spring-security intercepts this xxx link, and jumps to the login interface 4. After the user log-in, Requestcacheawarefilter this interceptor, and then return the XXX to the browser
However, we are here to integrate the CAs to do the login, then, the tragedy happened.
public void DoFilter (ServletRequest request, servletresponse response, Filterchain chain) throws IOException, servletexception {HttpServletRequest wrappedsavedrequest = requestcache.getmatchingrequest ((HTTPSERVL
etrequest) request, (HttpServletResponse) response);
Chain.dofilter (wrappedsavedrequest = = null? request:wrappedsavedrequest, response); }</code></pre> This filter will call a method of Requestcache, Requestcache is the cache store used in spring to cache browser request requests. This method is as follows: <pre><code>public httpservletrequest getmatchingrequest (httpservletrequest request, Http
Servletresponse response) {Defaultsavedrequest saved = (defaultsavedrequest) getrequest (Request,
Response);
if (saved = = null) {return null;
} if (!saved.doesrequestmatch (request, Portresolver)) {Logger.debug ("saved request doesn ' t match");
return null; } removerequest (Request, response);
return new Savedrequestawarewrapper (saved, request);
}
There is a line called remverequest, this line of code will be the existence of Requestcache in the request path to clear. This request path is the path to which the browser jumps when the user presses the fallback button. See the following logic specifically:
When the user presses the fallback button, it is in fact returned to the Spring-cas provided by the J_spring_cas_security_check this URL, will eventually go to <pre><code> In the savedrequestawareauthenticationsuccesshandler</code></pre>, decide which page to jump to:
Savedrequest savedrequest = requestcache.getrequest (request, response);
if (savedrequest = = null) {super.onauthenticationsuccess (request, response, authentication);
Return
} String Targeturlparameter = Gettargeturlparameter (); if (Isalwaysusedefaulttargeturl () | | | (Targeturlparameter! = null && stringutils.hastext (Request.getparameter (Targeturlparameter))))
{requestcache.removerequest (request, response);
Super.onauthenticationsuccess (Request, response, authentication);
Return
} clearauthenticationattributes (Request);
Use the defaultsavedrequest URL String targeturl = Savedrequest.getredirecturl ();
Logger.debug ("Redirecting to Defaultsavedrequest Url:" + targeturl);
Getredirectstrategy (). Sendredirect (Request, response, TargetUrl);
As can be seen, if the Requestcache request path is empty, then it will jump to the default path, if you do not configure in spring, the default is your application access to the context of the path, if there is no home page under the path, it will naturally reported 404 error. Solution:
There is no good solution, at the moment we are just rough Requestcache implementation class Httpsessionrequestcache rewrite a piece, add a logic of judgment:
public void Removerequest (HttpServletRequest currentrequest, httpservletresponse response) {HttpSession ses
sion = Currentrequest.getsession (false);
if (session! = NULL) {logger.debug ("removing defaultsavedrequest from session if present");
Object obj = Session.getattribute (saved_request);
if (obj instanceof defaultsavedrequest) {defaultsavedrequest savedrequest = (defaultsavedrequest) obj;
String RequestUri = Savedrequest.getrequesturi ();
System.out.println ("Requestcache....requesturi ..." + Savedrequest.getrequesturi ());
if (Requesturi.contains ("/api/oauth/")) {return;
}} session.removeattribute (Saved_request); }
}