Spring boot KerberosLoginFailureHandler forward to /login.html loop -
i using spring boot 1.5.4.release spring-security-kerberos-web 1.0.1.release
the setup working when test in dev server.
when test in local sso fail expect because hostname not same service principal in keytab.
in authenticationfailurehandler kerberos, if forward request /login.html cause infinite loop:
request.getrequestdispatcher(loginpath).forward(request, response); if change sendredirect cause getauthentication() return null:
response.sendredirect(request.getcontextpath() + loginpath); securitycontextholder.getcontext().getauthentication() == null; please help, stuck in spring boot config, other project same config working without issue (spring 4.2.5.release + spring-security-kerberos-web 1.0.1.release)
current workaround override spnegoauthenticationprocessingfilter.dofilter bypass if login.html contain "negotiate" header:
@bean public spnegoauthenticationprocessingfilter spnegoauthenticationprocessingfilter(authenticationmanager authenticationmanager1) throws exception { spnegoauthenticationprocessingfilter filter = new spnegoauthenticationprocessingfilter(){ private authenticationdetailssource<httpservletrequest,?> authenticationdetailssource = new webauthenticationdetailssource(); private authenticationmanager authenticationmanager = authenticationmanager1; private authenticationsuccesshandler successhandler = loginsuccesshandler(); private authenticationfailurehandler failurehandler = kerberosloginfailurehandler(); private sessionauthenticationstrategy sessionstrategy = new nullauthenticatedsessionstrategy(); private boolean skipifalreadyauthenticated = true; @override public void dofilter(servletrequest req, servletresponse res, filterchain chain) throws ioexception, servletexception { httpservletrequest request = (httpservletrequest) req; httpservletresponse response = (httpservletresponse) res; if (skipifalreadyauthenticated) { authentication existingauth = securitycontextholder.getcontext().getauthentication(); if (existingauth != null && existingauth.isauthenticated() && (existingauth instanceof anonymousauthenticationtoken) == false) { chain.dofilter(request, response); return; } } string header = request.getheader("authorization"); string requesturl = ((httpservletrequest)req).getrequesturl().tostring(); if (requesturl.indexof(securityconfig.getloginpath()) < 0 && header != null && (header.startswith("negotiate ") || header.startswith("kerberos "))) { if (logger.isdebugenabled()) { logger.debug("received negotiate header request " + request.getrequesturl() + ": " + header); } byte[] base64token = header.substring(header.indexof(" ") + 1).getbytes("utf-8"); byte[] kerberosticket = base64.decode(base64token); kerberosservicerequesttoken authenticationrequest = new kerberosservicerequesttoken(kerberosticket); authenticationrequest.setdetails(authenticationdetailssource.builddetails(request)); authentication authentication; try { authentication = authenticationmanager.authenticate(authenticationrequest); } catch (authenticationexception e) { // shouldn't happen, wrong // configuration on server side logger.warn("negotiate header invalid: " + header, e); securitycontextholder.clearcontext(); if (failurehandler != null) { failurehandler.onauthenticationfailure(request, response, e); } else { response.setstatus(httpservletresponse.sc_internal_server_error); response.flushbuffer(); } return; } sessionstrategy.onauthentication(authentication, request, response); securitycontextholder.getcontext().setauthentication(authentication); if (successhandler != null) { successhandler.onauthenticationsuccess(request, response, authentication); } } chain.dofilter(request, response); } }; filter.setfailurehandler(kerberosloginfailurehandler()); filter.setauthenticationmanager(authenticationmanager1); return filter; }
Comments
Post a Comment