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; } }
如上几步就可以成功配置双重拦截了