Spring 使用方法级安全性处理拒绝访问
我有一个用spring security保护的方法,如下所示:Spring 使用方法级安全性处理拒绝访问,spring,spring-security,Spring,Spring Security,我有一个用spring security保护的方法,如下所示: @PreAuthorize("hasRole('add_user')") public void addUser(User user) ; 如果没有enoguh权限的用户试图调用它 ,将引发accessDenied异常: org.springframework.security.access.AccessDeniedException: Access is denied 这是预期的,但问题是,为什么定义的拒绝访问处理程序 在se
@PreAuthorize("hasRole('add_user')")
public void addUser(User user) ;
如果没有enoguh权限的用户试图调用它
,将引发accessDenied异常:
org.springframework.security.access.AccessDeniedException: Access is denied
这是预期的,但问题是,为什么定义的拒绝访问处理程序
在security.xml中,配置文件不工作:
<access-denied-handler error-page="accessDenied"/>
根据spring安全文档,元素的“拒绝访问页面”属性的用户在spring 3.0及更高版本中已被弃用 我们在应用程序中执行以下操作:
AccessDeniedHandlerImpl
,创建自定义拒绝访问处理程序李>
setErrorPage
方法,输入将显示访问被拒绝页面的控制器的名称super.handle(\u请求,\u响应,\u异常)代码>位于处理程序的末尾。Spring将控制转发到上面#2中列出的控制器
这是我的访问被拒绝控制器-我应该早点发布-对此表示抱歉。为了打开拒绝访问页面,我必须使用重定向:
@Controller
public class AccessDeniedController {
private static Logger logger = Logger.getLogger(AccessDeniedController.class);
@RequestMapping(value = "/securityAccessDenied")
public String processAccessDeniedException(){
logger.info("Access Denied Handler");
return "redirect:/securityAccessDeniedView";
}
@RequestMapping(value = "/securityAccessDeniedView")
public String displayAccessDeniedView(){
logger.info("Access Denied View");
return "/SecurityAccessDenied";
}
请让我知道,如果这不能解决它,我会继续挖掘-我刚刚在本地测试了它,这应该可以做到。
}仅当用户没有访问资源的权限时,Spring Security才会重定向到“拒绝访问”页面。也就是说,当用户经过身份验证但不具有允许的角色时
但当问题不是授权而是身份验证时,Spring Security会重定向到登录页面(让用户自己进行身份验证),而不是拒绝访问页面
由于您有一个规则检查规则中的“isAuthenticated()”,因此不会将您重定向到拒绝访问页面,而是重定向到登录页面
希望能有所帮助。我自己也遇到了同样的问题,并发布了另一个与同样问题相关的问题。经过几个小时的反复研究,我终于找到了解决问题的办法。我知道这个问题已经2年多了,但我想我会用信息更新它,以防它对其他人有价值
简而言之,我注意到,SimpleMappingExceptionResolver
正在处理异常并使用默认映射解析它。因此,没有任何异常可以将堆栈冒泡到ExceptionTranslationFilter
,它将重定向到拒绝访问处理程序
请参阅以获取更多信息。也许提供了一些线索?此示例是自定义实现,因为他想在出现拒绝访问时向会话添加额外数据,所以我不需要此自定义,我只需要默认行为。请发布完整的安全配置。@fresh\u dev:您所说的“不工作”到底是什么意思?@Ralph,更新了问题,解释了不起作用的情况。上面的代码对我不起作用,会抛出accessDeniedException,但用户不会重定向到拒绝访问页面@jcurtin它对我也不起作用,抛出了异常,但用户没有重定向到自定义拒绝访问处理程序ref,知道为什么吗?@fresh_dev-这对你们有帮助吗?正如我之前告诉过你们的,它首先不会进入AccessDeniedHandlerApp类,这是关键问题。
DEBUG [http-bio-8080-exec-1] (PrePostAnnotationSecurityMetadataSource.java:93) - @org.springframework.security.access.prepost.PreAuthorize(value=hasRole('add_user')) found on specific method: public void com.myapp.service.impl.UserServiceImpl.addUser(com.myapp.domain.User) throws java.lang.Exception,org.springframework.security.access.AccessDeniedException
DEBUG [http-bio-8080-exec-1] (DelegatingMethodSecurityMetadataSource.java:66) - Adding security method [CacheKey[com.myapp.service.impl.UserServiceImpl; public abstract void com.myapp.service.UserService.addUser(com.myapp.domain.User) throws java.lang.Exception,org.springframework.security.access.AccessDeniedException]] with attributes [[authorize: 'hasRole('add_user')', filter: 'null', filterTarget: 'null']]
DEBUG [http-bio-8080-exec-1] (AbstractSecurityInterceptor.java:191) - Secure object: ReflectiveMethodInvocation: public abstract void com.myapp.service.UserService.addUser(com.myapp.domain.User) throws java.lang.Exception,org.springframework.security.access.AccessDeniedException; target is of class [com.myapp.service.impl.UserServiceImpl]; Attributes: [[authorize: 'hasRole('add_user')', filter: 'null', filterTarget: 'null']]
DEBUG [http-bio-8080-exec-1] (AbstractSecurityInterceptor.java:292) - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@c650d918: Principal: org.springframework.security.core.userdetails.User@db344023: Username: user@mycomp.com; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: access_viewUsers; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffde5d4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: E6BBAC0CD4499B1455227DC6035CC882; Granted Authorities: access_viewUsers
DEBUG [http-bio-8080-exec-1] (AffirmativeBased.java:53) - Voter: org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter@1d1e082e, returned: -1
DEBUG [http-bio-8080-exec-1] (AffirmativeBased.java:53) - Voter: org.springframework.security.access.vote.RoleVoter@1eab12f1, returned: 0
DEBUG [http-bio-8080-exec-1] (AffirmativeBased.java:53) - Voter: org.springframework.security.access.vote.AuthenticatedVoter@71689bf1, returned: 0
public class AccessDeniedHandlerApp extends AccessDeniedHandlerImpl {
private static Logger logger = Logger.getLogger(AccessDeniedHandlerApp.class);
private static final String LOG_TEMPLATE = "AccessDeniedHandlerApp: User attempted to access a resource for which they do not have permission. User %s attempted to access %s";
@Override
public void handle(HttpServletRequest _request, HttpServletResponse _response, AccessDeniedException _exception) throws IOException, ServletException {
setErrorPage("/securityAccessDenied"); // this is a standard Spring MVC Controller
// any time a user tries to access a part of the application that they do not have rights to lock their account
<custom code to lock the account>
super.handle(_request, _response, _exception);
}
<http auto-config='true'>
<intercept-url pattern="/views/**" access="ROLE_USER" />
<form-login login-page="/Login.jsp" authentication-success-handler-ref="loginSuccessFilter"
authentication-failure-handler-ref="loginFailureFilter" />
<logout logout-success-url="/home" />
<access-denied-handler ref="customAccessDeniedHandler"/>
</http>
<beans:bean id="customAccessDeniedHandler" class="org.demo.security.AccessDeniedHandlerApp"/>
@Controller
public class AccessDeniedController {
private static Logger logger = Logger.getLogger(AccessDeniedController.class);
@RequestMapping(value = "/securityAccessDenied")
public String processAccessDeniedException(){
logger.info("Access Denied Handler");
return "redirect:/securityAccessDeniedView";
}
@RequestMapping(value = "/securityAccessDeniedView")
public String displayAccessDeniedView(){
logger.info("Access Denied View");
return "/SecurityAccessDenied";
}