某些授权例外的自定义目标

时间:2014-09-25 03:25:32

标签: spring spring-security

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

要获得此角色,您需要填写某种表格。

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

我想要达到的目的是让用户自动重定向到他们需要填写的表格,然后升级到ROLE_A"。所以,我可以处理升级并移动它们。

有关如何实现这一目标的任何建议吗?

3 个答案:

答案 0 :(得分:1)

你可以在春天使用拦截器实现这一点。在spring docs中查看如何设置拦截器...它非常简单。拦截器实现HandlerInterceptor接口。在preHandle方法中,您可以在请求到达控制器之前对请求执行处理。所以在你的情况下,你可以在拦截器的preHandle方法中编写代码来检查用户的角色,如果它们不是ROLE_A,那么你可以将它们重定向到表单。像下面这样的东西会做得很好:

@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;
}

答案 1 :(得分:1)

  1. 首先创建自己的自定义accessDenied Handlder。
    public class CustomAccessDeniedHandler implements AccessDeniedHandler {
    	
    	private String redirectPage;
    
    	public void setRedirectPage(String redirectPage) {
    		this.redirectPage = redirectPage;
    	}
    
    	/**
    	 * Redirect to our redirectPage page instead of login page.
    	 */
    	@Override
    	public void handle(HttpServletRequest request,
    			HttpServletResponse response,
    			AccessDeniedException accessDeniedException) throws IOException,
    			ServletException {
    		 String redirectUrl = request.getContextPath()+redirectPage;
    	        redirectUrl = response.encodeRedirectURL(redirectUrl);
    		
         response.sendRedirect(redirectUrl);
    		
    	}
    	
    	
    
    }
  2. @。将此自定义处理程序的bean定义到spring-security.xml文件中。并将重定向页面URL注入此自定义处理程序。

    <beans:bean id = "accessDeniedHandler" class = "com.own.web.security.handler.CustomAccessDeniedHandler">
    	 <beans:property name="redirectPage" value="/rediectPage" />
    	</beans:bean>

    1. 将访问权限拒绝处理程序标记定义到spring-security.xml文件中,并引用此customAccessDenied处理程序bean标识。
      <access-denied-handler ref="accessDeniedHandler"/>
    2. 用户应具有访问您要重定向的网页的角色

答案 2 :(得分:0)

所以,这就是我最终做的事情:

    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));
    }
}