Spring security4.1.4 如何实现api接口和页面的双重拦截

dileber先暂缓一下,最近在作服务器认证方面的东西

貌似市面上关于双重拦截的比较少,而且版本都比较旧 ,我今天就给大家讲讲spring secutiry的双重拦截,下回我再讲讲shiro的双重拦截。最近做东西比较杂乱~~哈哈

首先讲一下spring Security入和对接口和页面同时拦截

首先是配置文件

<beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:beans="http://www.springframework.org/schema/beans" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/security
   http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <!-- enable use-expressions -->  <http auto-config="true" use-expressions="true" entry-point-ref="MyAuthenticationEntryPoint">

不拦截的接口
        <intercept-url pattern="/customer" access="permitAll"></intercept-url>

       

拦截的api
        <intercept-url pattern="api/cv1/**" access="hasRole('ROLE_USER')" />
       
拦截的网页
        <intercept-url pattern="/customer/**" access="hasRole('ROLE_USER')" />
        页面登录  <custom-filter ref="loginFilter" after="FORM_LOGIN_FILTER"/>
ajax登录
        <custom-filter ref="ajaxLoginFilter" before="FORM_LOGIN_FILTER"/>
开启csrf,之前的博客我也有说个csrf 你们自己看看就好  <!-- enable csrf protection -->  <!--<csrf/>-->  </http>   <beans:bean id="MyAuthenticationEntryPoint" class="com.cs.jucaibang.back_end.utils.springsecurity.MyAuthenticationEntryPoint">
        <beans:property name="loginFormUrl" value="/customer/login" />
    </beans:bean>

    <!-- 验证ajax请求,配置 开始-->  <beans:bean id="ajaxLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
        <beans:property name="authenticationManager" ref="authenticationManager"/>
        <beans:property name="authenticationFailureHandler" ref="ajaxFailureHandler"/>
        <beans:property name="authenticationSuccessHandler" ref="ajaxSuccessHandler"/>
        <beans:property name="filterProcessesUrl" value="/api/login"/>
        <beans:property name="passwordParameter" value="passWord"/>
        <beans:property name="usernameParameter" value="userName"/>
    </beans:bean>

    <beans:bean id="ajaxFailureHandler" class="com.utils.springsecurity.AjaxAuthenticationFailureHandler">
    </beans:bean>

    <beans:bean id="ajaxSuccessHandler" class="com.utils.springsecurity.AjaxAuthenticationSuccessHandler">
    </beans:bean>
    <!-- 验证ajax请求,配置 结束-->    <!--普通请求,配置开始 -->  <beans:bean id="loginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
        <beans:property name="authenticationManager" ref="authenticationManager"/>
        <beans:property name="authenticationFailureHandler" ref="failureHandler"/>
        <beans:property name="authenticationSuccessHandler" ref="successHandler"/>
        <beans:property name="filterProcessesUrl" value="/customer/login"/>
        <beans:property name="passwordParameter" value="passWord"/>
        <beans:property name="usernameParameter" value="userName"/>
    </beans:bean>

    <beans:bean id="failureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
        <beans:property name="defaultFailureUrl" value="/err/403" />
    </beans:bean>

    <beans:bean id="successHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
        <beans:property name="alwaysUseDefaultTargetUrl" value="false"/>
        <beans:property name="defaultTargetUrl" value="/"/>
    </beans:bean>
    <!--普通请求,配置结束 -->    

    <!-- Select users and user_roles from database -->  <authentication-manager  alias="authenticationManager">
        <authentication-provider ref='commonAuthenticationProvider'/>
        <!-- <authentication-provider>  <jdbc-user-service  data-source-ref="dataSource"  users-by-username-query=  "select username,password, enabled from users where username=?"  authorities-by-username-query=  "select username, role from user_roles where username =? " />  </authentication-provider>-->  </authentication-manager>
   
    
    <global-method-security secured-annotations="enabled" />
</beans:beans>




实现

AuthenticationFailureHandler

/**  * Created by yy on 2016/1/12.  */ public class AjaxAuthenticationFailureHandler implements AuthenticationFailureHandler {

    public AjaxAuthenticationFailureHandler() {
    }

    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.setContentType("application/json");
        httpServletResponse.setCharacterEncoding("UTF-8");
        PrintWriter out = httpServletResponse.getWriter();
        DataWrapper dataWrapper = new DataWrapper();
        dataWrapper.setStatus(-1);
        dataWrapper.setMsg("登录失败");
        out.println(StringHelper.JsonHelper.toJson(dataWrapper));
        out.flush();
        out.close();
    }
}

同上


/**  * Created by yy on 2016/1/12.  */ public class AjaxAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    public AjaxAuthenticationSuccessHandler() {
    }

    @Autowired
    UserService service;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        httpServletResponse.setContentType("application/json");
        httpServletResponse.setCharacterEncoding("UTF-8");
        PrintWriter out = httpServletResponse.getWriter();
        ModelUserAuth user = (ModelUserAuth) authentication.getPrincipal();
        WrapperJcbLogin result=service.spring_login(user.getUserName(), httpServletRequest);
        out.println(StringHelper.JsonHelper.toJson(result));
        out.flush();
        out.close();
    }
}


同上



/**  * Created by yy on 2016/1/12.  */ public class MyAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
    static Pattern apiPattern= Pattern.compile("^/[a-z]v[0-1]/(w|r)/");

    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
            throws IOException, ServletException {

        String redirectUrl = null;

        String url = request.getRequestURI();


        Matcher m=apiPattern.matcher(url);
        if( m.find()){
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            PrintWriter out = response.getWriter();
            DataWrapper dataWrapper = new DataWrapper();
            dataWrapper.setStatus(-1);
            dataWrapper.setMsg("您还未登录");
            out.println(StringHelper.JsonHelper.toJson(dataWrapper));
            out.flush();
            out.close();
        }else{
            if (this.isUseForward()) {

                if (this.isForceHttps() && "http".equals(request.getScheme())) {
                    // First redirect the current request to HTTPS.
                    // When that request is received, the forward to the login page will be used.
                    redirectUrl = buildHttpsRedirectUrlForRequest(request);
                }

                if (redirectUrl == null) {
                    String loginForm = determineUrlToUseForThisRequest(request, response, authException);

                    RequestDispatcher dispatcher = request.getRequestDispatcher(loginForm);

                    dispatcher.forward(request, response);

                    return;
                }
            } else {
                // redirect to login page. Use https if forceHttps true

                redirectUrl = buildRedirectUrlToLoginPage(request, response, authException);

            }

            redirectStrategy.sendRedirect(request, response, redirectUrl);
        }

    }


}



/**  * Created by yy on 2016/1/11.  * 对spring security 拦截的重写  *  */ public class MySpringAccessDeniedHandler implements AccessDeniedHandler {


    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        boolean isAjax = "XMLHttpRequest".equals(httpServletRequest.getHeader("X-Requested-With"));
        //如果是ajax请求
        if (isAjax) {
            httpServletResponse.setContentType("application/json");
            httpServletResponse.setCharacterEncoding("UTF-8");
            PrintWriter out = httpServletResponse.getWriter();
            DataWrapper dataWrapper = new DataWrapper();
            dataWrapper.setStatus(-1);
            dataWrapper.setMsg("403");
            out.println(StringHelper.JsonHelper.toJson(dataWrapper));
            out.flush();
            out.close();
            return;
        }
        else if (!httpServletResponse.isCommitted()) {
            if (clientErrorPage != null) {
                // Put exception into request scope (perhaps of use to a view)
                httpServletRequest.setAttribute(WebAttributes.ACCESS_DENIED_403, accessDeniedException);

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

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

    }

    private String clientErrorPage;

    public void setClientErrorPage(String clientErrorPage) {

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


}
 
 
如上几步就可以成功配置双重拦截了   



你可能感兴趣的:(java,spring,spring,Security,ajax拦截)