IE8 shows standard error page instead of declared one in Spring Security -
i have configured spring security show custom error page during authorisation process. works fine in firefox, opera , chrome not in ie8. browser shows default page 403 http code instead of defined 1 in spring config file. make use of preauthenticated scenario time check user privileges, or authenitcated , make decision whether permit him/her access requested url.
here configuration of web.xml
<filter> <filter-name>filterchainproxy</filter-name> <filter-class>org.springframework.web.filter.delegatingfilterproxy</filter-class> </filter> <filter-mapping> <filter-name>filterchainproxy</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <login-config> <auth-method>basic</auth-method> <realm-name>testing realm</realm-name> </login-config> <security-role> <role-name>*</role-name> </security-role> <security-constraint> <display-name>free access</display-name> <web-resource-collection> <web-resource-name>free access pages</web-resource-name> <url-pattern>/denied.html</url-pattern> <http-method>get</http-method> </web-resource-collection> </security-constraint> <!-- enforce authentication, authorisation performed application --> <security-constraint> <display-name>restricted access</display-name> <web-resource-collection> <web-resource-name>all areas</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>*</role-name> </auth-constraint> </security-constraint>
and security related configuration:
<bean id="filterchainproxy" class="org.springframework.security.web.filterchainproxy"> <sec:filter-chain-map path-type="ant"> <sec:filter-chain pattern="/**" filters="sif,j2eepreauthfilter,logoutfilter,etf,fsi" /> </sec:filter-chain-map> </bean> <bean id="sif" class="org.springframework.security.web.context.securitycontextpersistencefilter" /> <sec:authentication-manager alias="authenticationmanager"> <sec:authentication-provider ref='preauthenticatedauthenticationprovider' /> </sec:authentication-manager> <bean id="preauthenticatedauthenticationprovider" class="org.springframework.security.web.authentication.preauth.preauthenticatedauthenticationprovider"> <property name="preauthenticateduserdetailsservice" ref="preauthenticateduserdetailsservice" /> </bean> <bean id="preauthenticateduserdetailsservice" class="org.springframework.security.web.authentication.preauth.preauthenticatedgrantedauthoritiesuserdetailsservice" /> <bean id="j2eepreauthfilter" class="org.springframework.security.web.authentication.preauth.j2ee.j2eepreauthenticatedprocessingfilter"> <property name="authenticationmanager" ref="authenticationmanager" /> <property name="authenticationdetailssource"> <bean class="pl.company.spring.j2eebasedpreauthenticatedwebauthenticationdetailssourcefromdatabase"> <property name="mappablerolesretriever"> <bean class="pl.company.spring.databasemappableattributesretriever" /> </property> <property name="userroles2grantedauthoritiesmapper"> <bean class="org.springframework.security.core.authority.mapping.simpleattributes2grantedauthoritiesmapper"> <property name="convertattributetouppercase" value="true" /> </bean> </property> </bean> </property> </bean> <!-- <bean id="preauthenticatedprocessingfilterentrypoint" class="org.springframework.security.web.authentication.http403forbiddenentrypoint" /> --> <bean id="preauthenticatedprocessingfilterentrypoint" class="pl.ivmx.cbp.spring.http403forbiddenentrypoint"> <property name="errorpage" value="/denied.html"/> </bean> <bean id="logoutfilter" class="org.springframework.security.web.authentication.logout.logoutfilter"> <constructor-arg value="/" /> <constructor-arg> <list> <bean class="org.springframework.security.web.authentication.logout.securitycontextlogouthandler" /> </list> </constructor-arg> </bean> <bean id="servletcontext" class="org.springframework.web.context.support.servletcontextfactorybean" /> <bean id="etf" class="org.springframework.security.web.access.exceptiontranslationfilter"> <property name="authenticationentrypoint" ref="preauthenticatedprocessingfilterentrypoint" /> <property name="accessdeniedhandler" ref="accessdeniedhandler"/> </bean> <bean id="accessdeniedhandler" class="pl.company.spring.myaccessdeniedhandlerimpl"> <property name="errorpage" value="/denied.html"/> </bean> <bean id="httprequestaccessdecisionmanager" class="org.springframework.security.access.vote.unanimousbased"> <property name="allowifallabstaindecisions" value="false" /> <property name="decisionvoters"> <list> <ref bean="rolevoter" /> <ref bean="permissionvoter"/> <ref bean="authenticationvoter"/> </list> </property> </bean> <bean id="fsi" class="org.springframework.security.web.access.intercept.filtersecurityinterceptor"> <property name="authenticationmanager" ref="authenticationmanager" /> <property name="accessdecisionmanager" ref="httprequestaccessdecisionmanager" /> <property name="securitymetadatasource"> <sec:filter-invocation-definition-source> <! handled own voter --> <sec:intercept-url pattern="/cbp/rpc/ppecounter*" access="permission_ppecounter"/> <!-- handled role voter --> <sec:intercept-url pattern="/**" access="role_user" /> </sec:filter-invocation-definition-source> </property> </bean> <bean id="rolevoter" class="org.springframework.security.access.vote.rolevoter" /> <bean id="permissionvoter" class="pl.company.spring.permissionvoter"/> <bean id="authenticationvoter" class="org.springframework.security.access.vote.authenticatedvoter"/> <bean id="securitycontextholderawarerequestfilter" class="org.springframework.security.web.servletapi.securitycontextholderawarerequestfilter" />
what tried adding following snippet web.xml:
<error-page> <error-code>403</error-code> <location>/denied.html</location> </error-page>
but didn't helped. inspected code of accessdeniedhandlerimpl org.springframework.security.web.access package. handle method performs forward custom error page checked if response isn't commited:
public void handle(httpservletrequest request, httpservletresponse response, accessdeniedexception accessdeniedexception) throws ioexception, servletexception { if (!response.iscommitted()) { if (errorpage != null) { // put exception request scope (perhaps of use view) request.setattribute(webattributes.access_denied_403, accessdeniedexception); // set 403 status code. response.setstatus(httpservletresponse.sc_forbidden); // forward error page. requestdispatcher dispatcher = request.getrequestdispatcher(errorpage); dispatcher.forward(request, response); } else { response.senderror(httpservletresponse.sc_forbidden, accessdeniedexception.getmessage()); } } }
i had overriden class , added custom logging showed response wasn't commited , forward of request custom error page made.
the last point http403forbiddenentrypoint class used exceptiontranslationfilter. commence method looks this:
public void commence(httpservletrequest request, httpservletresponse response, authenticationexception arg2) throws ioexception, servletexception { if (logger.isdebugenabled()) { logger.debug("pre-authenticated entry point called. rejecting access"); } httpservletresponse httpresponse = (httpservletresponse) response; httpresponse.senderror(httpservletresponse.sc_forbidden, "access denied"); }
i have overriden method not send default error page nothing. in second try replicated code accessdeniedhandlerimpl perform forward. againt didn't ie8. debug log spring packets looks follows:
11:22:37,288 debug [exceptiontranslationfilter] access denied (user not anonymous); delegating accessdeniedhandler org.springframework.security.access.accessdeniedexception: access denied @ org.springframework.security.access.vote.unanimousbased.decide(unanimousbased.java:90) @ 11:22:37,289 debug [filterchainproxy] /denied.html @ position 1 of 5 in additional filter chain; firing filter: 'securitycontextpersistencefilter' 11:22:37,289 debug [filterchainproxy] /denied.html @ position 1 of 5 in additional filter chain; firing filter: 'securitycontextpersistencefilter' 11:22:37,290 debug [filterchainproxy] /denied.html @ position 2 of 5 in additional filter chain; firing filter: 'j2eepreauthenticatedprocessingfilter' 11:22:37,290 debug [filterchainproxy] /denied.html @ position 2 of 5 in additional filter chain; firing filter: 'j2eepreauthenticatedprocessingfilter' 11:22:37,290 debug [j2eepreauthenticatedprocessingfilter] checking secure context token: org.springframework.security.web.authentication.preauth.preauthenticatedauthenticationtoken@f9fdea61: principal: org.springframework.security.core.userdetails.user@6038c01: username: jarek; password: [protected]; enabled: true; accountnonexpired: true; credentialsnonexpired: true; accountnonlocked: true; not granted authorities; credentials: [protected]; authenticated: true; details: org.springframework.security.web.authentication.preauth.preauthenticatedgrantedauthoritieswebauthenticationdetails@b364: remoteipaddress: 0:0:0:0:0:0:0:1; sessionid: null; []; not granted authorities 11:22:37,290 debug [j2eepreauthenticatedprocessingfilter] checking secure context token: org.springframework.security.web.authentication.preauth.preauthenticatedauthenticationtoken@f9fdea61: principal: org.springframework.security.core.userdetails.user@6038c01: username: jarek; password: [protected]; enabled: true; accountnonexpired: true; credentialsnonexpired: true; accountnonlocked: true; not granted authorities; credentials: [protected]; authenticated: true; details: org.springframework.security.web.authentication.preauth.preauthenticatedgrantedauthoritieswebauthenticationdetails@b364: remoteipaddress: 0:0:0:0:0:0:0:1; sessionid: null; []; not granted authorities 11:22:37,290 debug [filterchainproxy] /denied.html @ position 3 of 5 in additional filter chain; firing filter: 'logoutfilter' 11:22:37,290 debug [filterchainproxy] /denied.html @ position 3 of 5 in additional filter chain; firing filter: 'logoutfilter' 11:22:37,290 debug [filterchainproxy] /denied.html @ position 4 of 5 in additional filter chain; firing filter: 'exceptiontranslationfilter' 11:22:37,290 debug [filterchainproxy] /denied.html @ position 4 of 5 in additional filter chain; firing filter: 'exceptiontranslationfilter' 11:22:37,290 debug [filterchainproxy] /denied.html @ position 5 of 5 in additional filter chain; firing filter: 'filtersecurityinterceptor' 11:22:37,290 debug [filterchainproxy] /denied.html @ position 5 of 5 in additional filter chain; firing filter: 'filtersecurityinterceptor' 11:22:37,290 debug [filterchainproxy] /denied.html reached end of additional filter chain; proceeding original chain 11:22:37,290 debug [filterchainproxy] /denied.html reached end of additional filter chain; proceeding original chain 11:22:37,290 debug [exceptiontranslationfilter] chain processed 11:22:37,290 debug [exceptiontranslationfilter] chain processed 11:22:37,291 debug [httpsessionsecuritycontextrepository] httpsession being created securitycontext non-default 11:22:37,291 debug [httpsessionsecuritycontextrepository] httpsession being created securitycontext non-default 11:22:37,291 warn [httpsessionsecuritycontextrepository] failed create session, response has been committed. unable store securitycontext. 11:22:37,291 warn [httpsessionsecuritycontextrepository] failed create session, response has been committed. unable store securitycontext. 11:22:37,291 debug [securitycontextpersistencefilter] securitycontextholder cleared, request processing completed 11:22:37,291 debug [securitycontextpersistencefilter] securitycontextholder cleared, request processing completed
i tried adding dispatching types spring filter:
<filter-mapping> <filter-name>filterchainproxy</filter-name> <url-pattern>/*</url-pattern> <dispatcher>error</dispatcher> <dispatcher>request</dispatcher> <dispatcher>include</dispatcher> <dispatcher>forward</dispatcher> </filter-mapping>
but again ie8 reluctant cooperate. hints how "force" ie8 show /denied.html welcomed.
make error page (denied.html) bigger 512 bytes. pad html spaces or whatever.
on client side, can disable "friendly error messages" in internet settings , ie show page if smaller 512 bytes.
Comments
Post a Comment