Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 特定授权例外的自定义目标_Spring_Spring Security - Fatal编程技术网

Spring 特定授权例外的自定义目标

Spring 特定授权例外的自定义目标,spring,spring-security,Spring,Spring Security,我有一个配置,访问网站的某些部分需要一个特定的角色:角色a 为了得到这个角色,你需要填写一张特定的表格 用户也可以在没有收到角色A的情况下通过初始注册,然后尝试访问这些需要角色A的区域。现在,我只向他们提供一个登录表单,告知他们没有足够的访问权限 我想实现的是,用户可以自动重定向到他们需要填写的表单,以“升级到角色”。这样,我就可以处理升级并让他们继续前进 关于如何实现这一点有什么建议吗?您可以在spring中使用拦截器来实现这一点。在spring文档中查看如何设置拦截器。。。这很简单。拦截器实

我有一个配置,访问网站的某些部分需要一个特定的角色:角色a

为了得到这个角色,你需要填写一张特定的表格

用户也可以在没有收到角色A的情况下通过初始注册,然后尝试访问这些需要角色A的区域。现在,我只向他们提供一个登录表单,告知他们没有足够的访问权限

我想实现的是,用户可以自动重定向到他们需要填写的表单,以“升级到角色”。这样,我就可以处理升级并让他们继续前进


关于如何实现这一点有什么建议吗?

您可以在spring中使用拦截器来实现这一点。在spring文档中查看如何设置拦截器。。。这很简单。拦截器实现HandlerInterceptor接口。在预处理方法中,您可以在请求到达控制器之前对请求执行处理。因此,在您的情况下,您可以使用拦截器的preHandle方法编写代码来检查用户的角色,如果他们不是角色,那么您可以将他们重定向到表单。下面这样做会很好:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // get the user's role from the session
    String role = (String) request.getSession().getAttribute("userRole");

    // validate user session when attempting to access pages
    String servletPath = request.getServletPath();
    // place all links in the if statement that you do not want users to be able to access without loggin in
    if (servletPath.endsWith("protectedPage.html")) {
        // make sure the user has a valid session
        if (role == null || !"ROLE_A".equals(role)) {
            // when the session is not valid (eg. session timed out, etc.) redirect user to index page
            response.sendRedirect("roleAForm.html");
    return false;
        }
    }

    return true;
}
  • 首先创建自己的自定义accessDenied Handlder。
    公共类CustomAccessDeniedHandler实现AccessDeniedHandler{
    私有字符串重定向页面;
    公共void setRedirectPage(字符串重定向页){
    this.redirectPage=重定向页面;
    }
    /**
    *重定向到我们的重定向页面,而不是登录页面。
    */
    @凌驾
    公共无效句柄(HttpServletRequest),
    HttpServletResponse,
    AccessDeniedException(AccessDeniedException)引发IOException,
    ServletException{
    String redirectUrl=request.getContextPath()+redirectPage;
    redirectUrl=response.encodeRedirectURL(重定向URL);
    sendRedirect(重定向URL);
    }
    
    }
    所以,我最后做的是:

        public class MyAccessDeniedHandler implements AccessDeniedHandler {
    
        @Inject
        @Named("securityMetadataSource")
        SecurityMetadataSource securityMetadata;
    
        @Override
        public void handle(
                HttpServletRequest request,
                HttpServletResponse response,
                AccessDeniedException accessDeniedException) throws IOException,
                ServletException {
    
            IUser user = RequestUtils.getUser(request);
    
            //The user is probably logged in but tried to enter an area he had no access to.        
            if(user != null){
    
                /*
                 * Check to see if this resource required endUserAccess
                 */
                FilterInvocation fi = new FilterInvocation(request.getContextPath(), request.getServletPath(), null);
    
                boolean requireEndUser = false;
                for(ConfigAttribute attr : securityMetadata.getAttributes(fi)){
                    String expression = attr.toString();
                    if(expression != null && expression.contains("ROLE_ENDUSER")){
                        requireEndUser = true;
                        break;
                    }
                }
    
                /*
                 * We have been denied access because we're missing the correct role 
                 */
                if(requireEndUser){
                    response.sendRedirect(URLUtils.addContextPath("/register/upgrade", request));
                    return;
                }
    
            }
            response.sendRedirect(URLUtils.addContextPath(URLUtils.getLogin(request),request));
        }
    }
    

    我不确定这是否解决了我的问题。有一组页面需要角色a,因此我认为需要能够引用intercept url对象,并能够说:“此资源是否需要角色a”和“此用户是否具有角色a”。也许我可以在这个拦截器中加载filterSecurityMetadataSource,并查询我们通常在表中存储用户角色的信息。因此,当用户登录时,我们检索并存储该用户会话中的所有相关信息(权限、角色等)。我认为它们必须是另一个对象,将页面映射到您的应用程序也可以访问的所需角色。可能是一个枚举或类似的东西,这样您就不必每次检查用户角色时都查询数据库。好的,我已经有了一个自定义的拒绝访问处理程序。但关键是如何确定此特定资源的访问被拒绝,因为用户缺少角色?请使用此注释。@PreAuthorize(“hasRole('ROLE_A')”)并将此批注放在controller上的方法上。如果用户缺少ROLE_A,请尝试在controller中访问此方法。然后spring将他重定向到访问被拒绝的处理程序