1 package org.springframework.security.web.authentication; 2 3 import java.io.IOException; 4 import javax.servlet.FilterChain; 5 import javax.servlet.ServletException; 6 import javax.servlet.ServletRequest; 7 import javax.servlet.ServletResponse; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 import org.springframework.context.ApplicationEventPublisher; 11 import org.springframework.context.ApplicationEventPublisherAware; 12 import org.springframework.context.MessageSource; 13 import org.springframework.context.MessageSourceAware; 14 import org.springframework.context.support.MessageSourceAccessor; 15 import org.springframework.security.authentication.AuthenticationDetailsSource; 16 import org.springframework.security.authentication.AuthenticationManager; 17 import org.springframework.security.authentication.InternalAuthenticationServiceException; 18 import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent; 19 import org.springframework.security.core.Authentication; 20 import org.springframework.security.core.AuthenticationException; 21 import org.springframework.security.core.SpringSecurityMessageSource; 22 import org.springframework.security.core.context.SecurityContextHolder; 23 import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy; 24 import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; 25 import org.springframework.security.web.util.matcher.AntPathRequestMatcher; 26 import org.springframework.security.web.util.matcher.RequestMatcher; 27 import org.springframework.util.Assert; 28 import org.springframework.web.filter.GenericFilterBean; 29 30 public abstract class AbstractAuthenticationProcessingFilter extends GenericFilterBean implements ApplicationEventPublisherAware, MessageSourceAware { 31 protected ApplicationEventPublisher eventPublisher;//應用事件發布者 32 protected AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();//身份驗證詳細信息源 33 private AuthenticationManager authenticationManager;//認證管理器 34 protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();//消息源訪問器 35 private RememberMeServices rememberMeServices = new NullRememberMeServices();//記住我的服務 36 private RequestMatcher requiresAuthenticationRequestMatcher;//請求匹配器 37 private boolean continueChainBeforeSuccessfulAuthentication = false;//成功認證前的繼續鏈 38 private SessionAuthenticationStrategy sessionStrategy = new NullAuthenticatedSessionStrategy();//會話認證策略 39 private boolean allowSessionCreation = true;//允許會話創建 40 private AuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();//身份驗證成功處理程序 41 private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();//身份驗證失敗處理程序 42 43 protected AbstractAuthenticationProcessingFilter(String defaultFilterProcessesUrl) {//默認過濾處理的url 44 this.setFilterProcessesUrl(defaultFilterProcessesUrl); 45 } 46 47 protected AbstractAuthenticationProcessingFilter(RequestMatcher requiresAuthenticationRequestMatcher) {//請求匹配器 48 Assert.notNull(requiresAuthenticationRequestMatcher, "requiresAuthenticationRequestMatcher cannot be null"); 49 this.requiresAuthenticationRequestMatcher = requiresAuthenticationRequestMatcher; 50 } 51 52 public void afterPropertiesSet() {//屬性集之后 53 Assert.notNull(this.authenticationManager, "authenticationManager must be specified"); 54 } 55 56 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 57 HttpServletRequest request = (HttpServletRequest)req; 58 HttpServletResponse response = (HttpServletResponse)res; 59 if (!this.requiresAuthentication(request, response)) { 60 chain.doFilter(request, response); 61 } else { 62 if (this.logger.isDebugEnabled()) { 63 this.logger.debug("Request is to process authentication"); 64 } 65 66 Authentication authResult; 67 try { 68 authResult = this.attemptAuthentication(request, response); 69 if (authResult == null) { 70 return; 71 } 72 73 this.sessionStrategy.onAuthentication(authResult, request, response); 74 } catch (InternalAuthenticationServiceException var8) { 75 this.logger.error("An internal error occurred while trying to authenticate the user.", var8); 76 this.unsuccessfulAuthentication(request, response, var8); 77 return; 78 } catch (AuthenticationException var9) { 79 this.unsuccessfulAuthentication(request, response, var9); 80 return; 81 } 82 83 if (this.continueChainBeforeSuccessfulAuthentication) { 84 chain.doFilter(request, response); 85 } 86 87 this.successfulAuthentication(request, response, chain, authResult); 88 } 89 } 90 91 protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {//是否需要認證
//請求匹配器與請求路勁是否匹配,如果匹配返回真,如果不匹配返回假 92 return this.requiresAuthenticationRequestMatcher.matches(request); 93 } 94 //認證邏輯的方法,由子類實現 95 public abstract Authentication attemptAuthentication(HttpServletRequest var1, HttpServletResponse var2) throws AuthenticationException, IOException, ServletException; 96 //認證成功 97 protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { 98 if (this.logger.isDebugEnabled()) { 99 this.logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult); 100 } 101 102 SecurityContextHolder.getContext().setAuthentication(authResult); 103 this.rememberMeServices.loginSuccess(request, response, authResult); 104 if (this.eventPublisher != null) {
//交互式認證成功事件 105 this.eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass())); 106 } 107 108 this.successHandler.onAuthenticationSuccess(request, response, authResult); 109 } 110 //沒有認證成功 111 protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException { 112 SecurityContextHolder.clearContext(); 113 if (this.logger.isDebugEnabled()) { 114 this.logger.debug("Authentication request failed: " + failed.toString(), failed); 115 this.logger.debug("Updated SecurityContextHolder to contain null Authentication"); 116 this.logger.debug("Delegating to authentication failure handler " + this.failureHandler); 117 } 118 119 this.rememberMeServices.loginFail(request, response); 120 this.failureHandler.onAuthenticationFailure(request, response, failed); 121 } 122 //get認證管理器 123 protected AuthenticationManager getAuthenticationManager() { 124 return this.authenticationManager; 125 } 126 //set認證管理器 127 public void setAuthenticationManager(AuthenticationManager authenticationManager) { 128 this.authenticationManager = authenticationManager; 129 } 130 //設置過濾器處理的url 131 public void setFilterProcessesUrl(String filterProcessesUrl) { 132 this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(filterProcessesUrl)); 133 } 134 //設置需要認證請求匹配器 135 public final void setRequiresAuthenticationRequestMatcher(RequestMatcher requestMatcher) { 136 Assert.notNull(requestMatcher, "requestMatcher cannot be null"); 137 this.requiresAuthenticationRequestMatcher = requestMatcher; 138 } 139 //get記住我的服務 140 public RememberMeServices getRememberMeServices() { 141 return this.rememberMeServices; 142 } 143 //set記住我的服務 144 public void setRememberMeServices(RememberMeServices rememberMeServices) { 145 Assert.notNull(rememberMeServices, "rememberMeServices cannot be null"); 146 this.rememberMeServices = rememberMeServices; 147 } 148 //set 是否跳出 鏈 在認證成功前 149 public void setContinueChainBeforeSuccessfulAuthentication(boolean continueChainBeforeSuccessfulAuthentication) { 150 this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication; 151 } 152 //set 應用事件發布者 153 public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) { 154 this.eventPublisher = eventPublisher; 155 } 156 //set 身份認證詳細信息源 157 public void setAuthenticationDetailsSource(AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource) { 158 Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required"); 159 this.authenticationDetailsSource = authenticationDetailsSource; 160 } 161 //set 消息源訪問器 162 public void setMessageSource(MessageSource messageSource) { 163 this.messages = new MessageSourceAccessor(messageSource); 164 } 165 // get 允許會話創建 166 protected boolean getAllowSessionCreation() { 167 return this.allowSessionCreation; 168 } 169 //set 允許會話創建 170 public void setAllowSessionCreation(boolean allowSessionCreation) { 171 this.allowSessionCreation = allowSessionCreation; 172 } 173 //set 會話認證策略 174 public void setSessionAuthenticationStrategy(SessionAuthenticationStrategy sessionStrategy) { 175 this.sessionStrategy = sessionStrategy; 176 } 177 //set 認證成功的處理程序 178 public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) { 179 Assert.notNull(successHandler, "successHandler cannot be null"); 180 this.successHandler = successHandler; 181 } 182 // set 認證失敗的處理程序 183 public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) { 184 Assert.notNull(failureHandler, "failureHandler cannot be null"); 185 this.failureHandler = failureHandler; 186 } 187 //get 認證成功的處理程序 188 protected AuthenticationSuccessHandler getSuccessHandler() { 189 return this.successHandler; 190 } 191 //get 認證失敗的處理程序 192 protected AuthenticationFailureHandler getFailureHandler() { 193 return this.failureHandler; 194 } 195 }