为了账号安全,请及时绑定邮箱和手机立即绑定

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

标签:
Java

貌似市面上关于双重拦截的比较少,而且版本都比较旧 ,我今天就给大家讲讲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;

    }

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

点击查看更多内容
16人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
81
获赞与收藏
3602

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消