摘要:返回總共需要處理個(gè)地方,一個(gè)是異常的處理,需要兼容請(qǐng)求,一個(gè)是成功返回的處理,一個(gè)是失敗返回的處理。這里就是攔截,獲取提交的參數(shù),然后交給去認(rèn)證。之后就是走后續(xù)的,如果成功,則會(huì)進(jìn)行相應(yīng)的配置。動(dòng)態(tài)配置權(quán)限筆記自定義
序
本文講述一下如何自定義spring security的登錄頁(yè),網(wǎng)上給的資料大多過(guò)時(shí),而且是基于后端模板技術(shù)的,講的不是太清晰,本文給出一個(gè)采用ajax的登錄及返回的前后端分離方式。
ajax返回ajax的異常處理總共需要處理3個(gè)地方,一個(gè)是異常的處理,需要兼容ajax請(qǐng)求,一個(gè)是成功返回的處理,一個(gè)是失敗返回的處理。
public class UnauthorizedEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { if(isAjaxRequest(request)){ response.sendError(HttpServletResponse.SC_UNAUTHORIZED,authException.getMessage()); }else{ response.sendRedirect("/login.html"); } } public static boolean isAjaxRequest(HttpServletRequest request) { String ajaxFlag = request.getHeader("X-Requested-With"); return ajaxFlag != null && "XMLHttpRequest".equals(ajaxFlag); } }
這里我們自定義成功及失敗的ajax返回,當(dāng)然這里我們簡(jiǎn)單處理,只返回statusCode
AjaxAuthSuccessHandlerpublic class AjaxAuthSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { response.setStatus(HttpServletResponse.SC_OK); } }AjaxAuthFailHandler
public class AjaxAuthFailHandler extends SimpleUrlAuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication failed"); } }security配置
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .exceptionHandling().authenticationEntryPoint(new UnauthorizedEntryPoint()) .and() .csrf().disable() .authorizeRequests() .antMatchers("/login","/css/**", "/js/**","/fonts/**").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login.html") .loginProcessingUrl("/login") .usernameParameter("name") .passwordParameter("password") .successHandler(new AjaxAuthSuccessHandler()) .failureHandler(new AjaxAuthFailHandler()) .permitAll() .and() .logout() .logoutUrl("/logout") .permitAll(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("admin").password("admin").roles("USER"); } }
這里有幾個(gè)要注意的點(diǎn):
permitAll
這里要添加前端資源路徑,以及登陸表單請(qǐng)求的接口地址/login
loginPage
這里設(shè)置登錄頁(yè)面的地址,這里我們用靜態(tài)頁(yè)面,即static目錄下的login.html
ajax配置
將authenticationEntryPoint,successHandler,failureHandler設(shè)置為上面自定義的ajax處理類
登錄頁(yè)面就是一個(gè)純粹的html頁(yè)面,其中登錄按鈕的ajax請(qǐng)求如下:
$.ajax({ url: "/login", type: "POST", data: "name="+name+"&password="+password, success: function (res, status) { window.location.href="/ok.html" }, error: function (res, status) { dangerDialog(res.statusText); } });
spring security內(nèi)置的各種filter:這里是請(qǐng)求/login,也就是spring security會(huì)默認(rèn)攔截的路徑,不了解spring security的人可能會(huì)納悶,我請(qǐng)求這個(gè)路徑,但是工程里頭沒有定義/login的request mapping,不要緊么。下面來(lái)剖析一下。
Alias | Filter Class | Namespace Element or Attribute |
---|---|---|
CHANNEL_FILTER | ChannelProcessingFilter | http/intercept-url@requires-channel |
SECURITY_CONTEXT_FILTER | SecurityContextPersistenceFilter | http |
CONCURRENT_SESSION_FILTER | ConcurrentSessionFilter | session-management/concurrency-control |
HEADERS_FILTER | HeaderWriterFilter | http/headers |
CSRF_FILTER | CsrfFilter | http/csrf |
LOGOUT_FILTER | LogoutFilter | http/logout |
X509_FILTER | X509AuthenticationFilter | http/x509 |
PRE_AUTH_FILTER | AbstractPreAuthenticatedProcessingFilter Subclasses | N/A |
CAS_FILTER | CasAuthenticationFilter | N/A |
FORM_LOGIN_FILTER | UsernamePasswordAuthenticationFilter | http/form-login |
BASIC_AUTH_FILTER | BasicAuthenticationFilter | http/http-basic |
SERVLET_API_SUPPORT_FILTER | SecurityContextHolderAwareRequestFilter | http/@servlet-api-provision |
JAAS_API_SUPPORT_FILTER | JaasApiIntegrationFilter | http/@jaas-api-provision |
REMEMBER_ME_FILTER | RememberMeAuthenticationFilter | http/remember-me |
ANONYMOUS_FILTER | AnonymousAuthenticationFilter | http/anonymous |
SESSION_MANAGEMENT_FILTER | SessionManagementFilter | session-management |
EXCEPTION_TRANSLATION_FILTER | ExceptionTranslationFilter | http |
FILTER_SECURITY_INTERCEPTOR | FilterSecurityInterceptor | http |
SWITCH_USER_FILTER | SwitchUserFilter | N/A |
UsernamePasswordAuthenticationFilter這里我們要關(guān)注的就是這個(gè)UsernamePasswordAuthenticationFilter,顧名思義,它是filter,在執(zhí)行/login請(qǐng)求的時(shí)候攔截,因而是不需要工程里頭去定義login的request mapping的。
spring-security-web-4.2.3.RELEASE-sources.jar!/org/springframework/security/web/authentication/UsernamePasswordAuthenticationFilter.java
public class UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter { public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { if (postOnly && !request.getMethod().equals("POST")) { throw new AuthenticationServiceException( "Authentication method not supported: " + request.getMethod()); } String username = obtainUsername(request); String password = obtainPassword(request); if (username == null) { username = ""; } if (password == null) { password = ""; } username = username.trim(); UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken( username, password); // Allow subclasses to set the "details" property setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); } //...... }
doc這里就是攔截,獲取login.html提交的參數(shù),然后交給authenticationManager去認(rèn)證。之后就是走后續(xù)的filter,如果成功,則會(huì)進(jìn)行相應(yīng)的session配置。
spring security動(dòng)態(tài)配置url權(quán)限
Spring Security筆記:自定義Login/Logout Filter、AuthenticationProvider、AuthenticationToken
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/11297.html
摘要:發(fā)現(xiàn)無(wú)效后,會(huì)返回一個(gè)的訪問(wèn)拒絕,不過(guò)可以通過(guò)配置類處理異常來(lái)定制行為。惡意用戶可能提交一個(gè)有效的文件,并使用它執(zhí)行攻擊。默認(rèn)是禁止進(jìn)行嗅探的。 前言 xss攻擊(跨站腳本攻擊):攻擊者在頁(yè)面里插入惡意腳本代碼,用戶瀏覽該頁(yè)面時(shí),腳本代碼就會(huì)執(zhí)行,達(dá)到攻擊者的目的。原理就是:攻擊者對(duì)含有漏洞的服務(wù)器注入惡意代碼,引誘用戶瀏覽受到攻擊的服務(wù)器,并打開相關(guān)頁(yè)面,執(zhí)行惡意代碼。xss攻擊方式...
摘要:準(zhǔn)備工作基本的配置就不說(shuō)了,網(wǎng)上一堆例子,只要弄到普通的表單登錄和自定義就可以。是基于的,因此才能在基于前起作用。這樣我們沒有破壞原有的獲取流程,還是可以重用父類原有的方法來(lái)處理表單登錄。 spring security用了也有一段時(shí)間了,弄過(guò)異步和多數(shù)據(jù)源登錄,也看過(guò)一點(diǎn)源碼,最近弄rest,然后順便搭oauth2,前端用json來(lái)登錄,沒想到spring security默認(rèn)居然不...
摘要:前言基于做微服務(wù)架構(gòu)分布式系統(tǒng)時(shí),作為認(rèn)證的業(yè)內(nèi)標(biāo)準(zhǔn),也提供了全套的解決方案來(lái)支持在環(huán)境下使用,提供了開箱即用的組件。 前言 基于SpringCloud做微服務(wù)架構(gòu)分布式系統(tǒng)時(shí),OAuth2.0作為認(rèn)證的業(yè)內(nèi)標(biāo)準(zhǔn),Spring Security OAuth2也提供了全套的解決方案來(lái)支持在Spring Cloud/Spring Boot環(huán)境下使用OAuth2.0,提供了開箱即用的組件。但...
摘要:寫在前面在一款應(yīng)用的整個(gè)生命周期,我們都會(huì)談及該應(yīng)用的數(shù)據(jù)安全問(wèn)題。用戶的合法性與數(shù)據(jù)的可見性是數(shù)據(jù)安全中非常重要的一部分。 寫在前面 在一款應(yīng)用的整個(gè)生命周期,我們都會(huì)談及該應(yīng)用的數(shù)據(jù)安全問(wèn)題。用戶的合法性與數(shù)據(jù)的可見性是數(shù)據(jù)安全中非常重要的一部分。但是,一方面,不同的應(yīng)用對(duì)于數(shù)據(jù)的合法性和可見性要求的維度與粒度都有所區(qū)別;另一方面,以當(dāng)前微服務(wù)、多服務(wù)的架構(gòu)方式,如何共享Sessi...
摘要:在整個(gè)學(xué)習(xí)過(guò)程中,我最關(guān)心的內(nèi)容有號(hào)幾點(diǎn),其中一點(diǎn)是前后端分離的情況下如何不跳轉(zhuǎn)頁(yè)面而是返回需要的返回值。登錄成功,不跳轉(zhuǎn)頁(yè)面,返回自定義返回值在官方文檔第節(jié),有這么一段描述要進(jìn)一步控制目標(biāo),可以使用屬性作為的替代。 在整個(gè)學(xué)習(xí)過(guò)程中,我最關(guān)心的內(nèi)容有號(hào)幾點(diǎn),其中一點(diǎn)是【前后端分離的情況下如何不跳轉(zhuǎn)頁(yè)面而是返回需要的返回值】。下面就說(shuō)一下學(xué)習(xí)結(jié)果,以xml配置位李。 登錄成功,不跳轉(zhuǎn)頁(yè)...
閱讀 2506·2021-11-23 09:51
閱讀 1289·2021-11-22 13:54
閱讀 3532·2021-09-24 10:31
閱讀 1265·2021-08-16 10:46
閱讀 3767·2019-08-30 15:54
閱讀 806·2019-08-30 15:54
閱讀 2963·2019-08-29 17:17
閱讀 3266·2019-08-29 15:08