spring security自定义AccessDeniedException权限异常处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_38373006/article/details/84339843

项目中需要根据url获取此url的权限,并做判断,若权限不足,throw new AccessDeniedException异常

项目中大多数前台访问请求为ajax请求,若为ajax请求,一般的需求为:若权限不足,直接前台提示,不做权限不足页面的跳转。

当然,为了满足可能某些项目会有<a>标签的超链接直接访问,还是在实现类里面做了两层判断

前提条件:

1,已经做了url的判断

authentication代表用户所拥有的权限,object代表url,
configAttributes代表请求url所需要的资源,

此方法为实现AccessDecisionManager后重写的方法

	public void decide(Authentication authentication, Object object,
			Collection<ConfigAttribute> configAttributes)
			throws AccessDeniedException, InsufficientAuthenticationException {
		if(configAttributes == null) {
			return;
		}
		//所请求的资源拥有的权限(一个资源对多个权限)
		Iterator<ConfigAttribute> iterator = configAttributes.iterator();
		while(iterator.hasNext()) {
			ConfigAttribute configAttribute = iterator.next();
			//访问所请求资源所需要的权限
			String needPermission = configAttribute.getAttribute();
			//用户所拥有的权限authentication
			for(GrantedAuthority ga : authentication.getAuthorities()) {
				if(needPermission.equals(ga.getAuthority())) {
					return;
				}
			}
		}
		//没有权限
		throw new AccessDeniedException("没有权限");
	}

2,spring-security.xml配置

<security:access-denied-handler ref="accessDeniedHandler"></security:access-denied-handler>
       <bean  id="accessDeniedHandler" class="com.infoland.security.CustomAccessDeniedHandler">
       		<property name="errorPage" value="/permissionerror.jsp"/>
       </bean>

3,具体实现类

/**
 * @Auther: lixiupeng
 * @Date: 2018/11/21 15:54
 * @Description: 自定义权限不足处理
 */
@Service
public class CustomAccessDeniedHandler implements AccessDeniedHandler {

    private String errorPage;

    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {


        //判断是否为ajax请求
        if (httpServletRequest.getHeader("accept").indexOf("application/json") > -1
                || (httpServletRequest.getHeader("X-Requested-With") != null && httpServletRequest.getHeader("X-Requested-With").equals(
                "XMLHttpRequest"))) {
            //设置状态为403,无权限状态
            httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
            //设置格式以及返回json数据 方便前台使用reponseJSON接取
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.setContentType("application/json; charset=utf-8");
            PrintWriter out = httpServletResponse.getWriter();
            JSONObject json = new JSONObject();
            json.put("message","权限不足,请联系管理员");
            out.append(json.toString());
        }else if(!httpServletResponse.isCommitted()){//非ajax请求
            if(errorPage!=null){
                // Put exception into request scope (perhaps of use to a view)
                httpServletRequest.setAttribute(WebAttributes.ACCESS_DENIED_403, e);

                // Set the 403 status code.
                httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);

                // forward to error page.
                RequestDispatcher dispatcher = httpServletRequest.getRequestDispatcher(errorPage);
                dispatcher.forward(httpServletRequest, httpServletResponse);
            }else{
                httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN,e.getMessage());
            }
        }
    }

    public void setErrorPage(String errorPage) {
        if ((errorPage != null) && !errorPage.startsWith("/")) {
            throw new IllegalArgumentException("errorPage must begin with '/'");
        }
        this.errorPage = errorPage;
    }
}

若xml配置中,需要配置自定义的jsp或者html,则实现类必须书写errorpage(名称自定义)以及set方法

若不配置errorpage,则会自动跳转系统默认的403页面

猜你喜欢

转载自blog.csdn.net/weixin_38373006/article/details/84339843