Rit*_*yak 16 java spring-mvc spring-security spring-3
我有一个spring 3应用程序,其配置如下.当任何用户尝试访问某个页面并且他/她未登录时,我会收到一个带有丑陋堆栈跟踪的Access is Denied异常.如何处理此异常并且不允许它转储堆栈跟踪.我实现了自己的访问被拒绝处理程序但不会被调用.
根据所请求资源的类型,我想显示自定义错误消息或页面.这是我的弹簧配置.
如何让Spring调用我的访问被拒绝处理程序.这是我的弹簧配置
<security:http auto-config='true'>
<security:intercept-url pattern="/static/**" filters="none"/>
<security:intercept-url pattern="/login" filters="none"/>
<security:intercept-url pattern="/**" access="ROLE_USER" />
<security:form-login login-page="/index"
default-target-url="/home" always-use-default-target="true"
authentication-success-handler-ref="AuthenticationSuccessHandler"
login-processing-url="/j_spring_security_check"
authentication-failure-url="/index?error=true"/>
<security:remember-me key="myLongSecretCookieKey" token-validity-seconds="1296000"
data-source-ref="jdbcDataSource" user-service-ref="AppUserDetailsService" />
<security:access-denied-handler ref="myAccessDeniedHandler" />
</security:http>
<bean id="myAccessDeniedHandler"
class="web.exceptions.handlers.AccessDeniedExceptionHandler">
<property name="errorPage" value="/public/403.htm" />
</bean>
Run Code Online (Sandbox Code Playgroud)
下面给出了处理此异常的自定义类
public class AccessDeniedExceptionHandler implements AccessDeniedHandler
{
private String errorPage;
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException arg2) throws IOException, ServletException {
response.sendRedirect(errorPage);
}
public void setErrorPage(String errorPage) {
if ((errorPage != null) && !errorPage.startsWith("/")) {
throw new IllegalArgumentException("errorPage must begin with '/'");
}
this.errorPage = errorPage;
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行此应用程序时,这是我得到的错误.我只粘贴了堆栈跟踪和Spring Debug日志的一部分.
20:39:46,173 DEBUG AffirmativeBased:53 - Voter: org.springframework.security.access.vote.RoleVoter@5b7da0d1, returned: -1
20:39:46,173 DEBUG AffirmativeBased:53 - Voter: org.springframework.security.access.vote.AuthenticatedVoter@14c92844, returned: 0
20:39:46,178 DEBUG ExceptionTranslationFilter:154 - Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:71)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:204)
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个问题?首先,我想阻止春天抛出那个例外.如果它仍然抛出它,我想处理它而不是举起任何旗帜.
更新:我也附加了我的web.xml的一部分.
<!-- Hibernate filter configuration -->
<filter>
<filter-name>HibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--Dispatcher Servlet -->
<servlet>
<servlet-name>rowz</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
Run Code Online (Sandbox Code Playgroud)
Roa*_*ner 12
在您的配置中您需要在您的站点上输入任何 URL 时始终对用户进行身份验证:
<security:intercept-url pattern="/**" access="ROLE_USER" />
Run Code Online (Sandbox Code Playgroud)
我认为您应该允许用户在进入登录页面时未经身份验证:
<security:intercept-url pattern="/your-login-page-url" access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/your-login-process-url" access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/your-login-failure-url" access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/**" access="ROLE_USER" />
Run Code Online (Sandbox Code Playgroud)
如果您使用的URL,如:/login/start,/login/error并且/login/failure您可以:
<security:intercept-url pattern="/login/**" access="ROLE_ANONYMOUS" />
<security:intercept-url pattern="/**" access="ROLE_USER" />
Run Code Online (Sandbox Code Playgroud)
更新:
具有此配置应该使框架将所有未经身份验证的(匿名)用户重定向到登录页面,并且所有用户都通过AccessDeniedHandler进行身份验证.该AccessDeniedException异常是框架的核心部分之一,而忽略它是不是一个好主意.如果您只提供Spring Security配置的部分内容,则很难提供更多帮助.
请务必阅读JavaDoc for ExceptionTranslationFilter,详细说明框架抛出的异常,默认情况下处理的原因和方式.
如果可能的话,尝试删除你添加的尽可能多的自定义部分,如AuthenticationSuccessHandler,RememberMeAuthenticationFilter和AccessDeniedHandler,看看问题是否有问题?尝试获取最小的集合并逐步添加新功能以查看错误的来源.
您在问题中未提及的一个重要事项是此错误消息的结果是什么?你明白了HTTP 500吗?还是HTTP 403?或者你被重定向到登录页面?
如果您在问题中提到,用户未经身份验证并且他/她被重定向到登录页面,那么这就是它的工作方式.看起来您只是因为您将级别设置为Spring Security类而得到ExceptionTranslationFilter:172记录的错误消息DEBUG.如果是这样,那也是它的工作方式,如果你不想记录错误,那么只需提高Spring Secyruty类的日志记录级别.
更新2:
与这些模式filters="none"必须匹配login-page,login-processing-url并且 authentication-failure-ur属性设置<security:form-login />跳过在显示的登录页面和处理在日志页面中的所有SpringSecurity检查.
<security:http auto-config='true'>
<security:intercept-url pattern="/static/**" filters="none"/>
<security:intercept-url pattern="/index" filters="none"/>
<security:intercept-url pattern="/j_spring_security_check" filters="none"/>
<security:intercept-url pattern="/**" access="ROLE_USER" />
<security:form-login login-page="/index"
default-target-url="/home" always-use-default-target="true"
authentication-success-handler-ref="AuthenticationSuccessHandler"
login-processing-url="/j_spring_security_check"
authentication-failure-url="/index?error=true"/>
<security:remember-me key="myLongSecretCookieKey" token-validity-seconds="1296000"
data-source-ref="jdbcDataSource" user-service-ref="AppUserDetailsService" />
<security:access-denied-handler ref="myAccessDeniedHandler" />
</security:http>
Run Code Online (Sandbox Code Playgroud)
AccessDeniedHandler在用户登录并且没有资源权限时调用(此处为source).如果要在用户未登录时处理登录页面请求,只需在security-context中配置:
<http ... entry-point-ref="customAuthenticationEntryPoint">
Run Code Online (Sandbox Code Playgroud)
并定义customAuthenticationEntryPoint:
<beans:bean id="customAuthenticationEntryPoint" class="pl.wsiadamy.webapp.controller.util.CustomAuthenticationEntryPoint">
</beans:bean>
Run Code Online (Sandbox Code Playgroud)
提示,不要试图与之抗争ExceptionTranslationFilter.我试图覆盖org.springframework.security.web.access.ExceptionTranslationFilter,没有效果:
<beans:bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
<beans:property name="authenticationEntryPoint" ref="customAuthenticationEntryPoint"/>
<beans:property name="accessDeniedHandler" ref="accessDeniedHandler"/>
</beans:bean>
<beans:bean id="accessDeniedHandler"
class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<beans:property name="errorPage" value="/accessDenied.htm"/>
</beans:bean>
Run Code Online (Sandbox Code Playgroud)
该ref="customAuthenticationEntryPoint"只是没有被调用.
您能检查一下您的 web.xml 是否支持转发请求吗?
errorPage 是一个 FORWARD 请求,并且大多数在 web.xml 中,我们仅支持重定向。只是想一想,你的代码对我来说看起来还不错。
已编辑
不同的观点,这仅取自工作代码。查看经过身份验证的选民类
禁用注释
<global-method-security pre-post-annotations="disabled"
secured-annotations="disabled" access-decision-manager-ref="accessDecisionManager">
</global-method-security>
Run Code Online (Sandbox Code Playgroud)
绕过过滤器
<http auto-config="true" use-expressions="true"
access-decision-manager-ref="accessDecisionManager"
access-denied-page="/accessDenied">
<intercept-url pattern="/appsecurity/login.jsp" filters="none" />
<intercept-url pattern="/changePassword" filters="none" />
<intercept-url pattern="/pageNotFound" filters="none" />
<intercept-url pattern="/accessDenied" filters="none" />
<intercept-url pattern="/forgotPassword" filters="none" />
<intercept-url pattern="/**" filters="none" />
<form-login login-processing-url="/j_spring_security_check"
default-target-url="/home" login-page="/loginDetails"
authentication-failure-handler-ref="authenticationExceptionHandler"
authentication-failure-url="/?login_error=t" />
<logout logout-url="/j_spring_security_logout"
invalidate-session="true" logout-success-url="/" />
<remember-me />
<!-- Uncomment to limit the number of sessions a user can have -->
<session-management invalid-session-url="/">
<concurrency-control max-sessions="1"
error-if-maximum-exceeded="true" />
</session-management>
</http>
Run Code Online (Sandbox Code Playgroud)
自定义决策投票器
<bean id="customVoter" class="xyz.appsecurity.helper.CustomDecisionVoter" />
Run Code Online (Sandbox Code Playgroud)
访问决策管理器
<!-- Define AccessDesisionManager as UnanimousBased -->
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">
<property name="decisionVoters">
<list>
<ref bean="customVoter" />
<!-- <bean class="org.springframework.security.access.vote.RoleVoter"
/> -->
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
身份验证异常处理程序
<bean id="authenticationExceptionHandler"
class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
<property name="exceptionMappings">
<props>
<!-- /error.jsp -->
<prop
key="org.springframework.security.authentication.BadCredentialsException">/?login_error=t</prop>
<!-- /getnewpassword.jsp -->
<prop
key="org.springframework.security.authentication.CredentialsExpiredException">/changePassword</prop>
<!-- /lockedoutpage.jsp -->
<prop key="org.springframework.security.authentication.LockedException">/?login_error=t</prop>
<!-- /unauthorizeduser.jsp -->
<prop
key="org.springframework.security.authentication.DisabledException">/?login_error=t</prop>
</props>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
32809 次 |
| 最近记录: |