• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Spring Security登陆流程讲解

java 搞代码 4年前 (2022-01-09) 11次浏览 已收录 0个评论

在Spring Security中,认证授权都是通过过滤器来实现的。

当开始登陆的时候,有一个关键的过滤器UsernamePasswordAuthenticationFilter,该类继承抽象类AbstractAuthenticationProcessingFilter,在AbstractAuthenticationProcessingFilter里有一个doFilter方法,一切先从这里说起。

private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
      throws IOException, ServletException {
   if (!requiresAuthentication(request, response)) {
      chain.doFilter(request, response);
      return;
   }
   try {
      Authentication authenticationResult = attemptAuthentication(request, response);
      if (authenticationResult == null) {
         // return immediately as subclass has indicated that it hasn't completed
         return;
      }
      this.sessionStrategy.onAuthentication(authenticationResult, request, response);
      // Authentication success
      if (this.continueChainBeforeSuccessfulAuthentication) {
         chain.doFilter(request, response);
      }
      successfulAuthentication(request, response, chain, authenticationResult);
   }
   catch (InternalAuthenticationServiceException failed) {
      this.logger.error("An internal error occurred while trying to authenticate the user.", failed);
      unsuccessfulAuthentication(request, response, failed);
   }
   catch (AuthenticationException ex) {
      // Authentication failed
      unsuccessfulAuthentication(request, response, ex);
   }
}

首先requiresAuthentication先判断是否尝试校验,通过后调用attemptAuthentication方法,这个方法也就是UsernamePasswordAuthenticationFilter 中的attemptAuthentication方法。

public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
      throws AuthenticationException {
   if (this.postOnly && !request.getMethod().equals("POST")) {
      throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
   }
   String username = obtainUsername(request);
   username = (username != null) ? username : "";
   username = username.trim();
   String password = obtainPassword(request);
   password = (password != null) ? password : "";
   UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
   // Allow subclasses to set the "details" property
   setDetails(request, authRequest);
   return this.getAuthenticationManager().authenticate(authRequest);
}

1.在UsernamePasswordAuthenticationFilter 的attemptAuthentication方法中,先是验证请求的类型,是否是POST请求,如果不是的话,抛出异常。(PS:登陆肯定要用POST方法了)
2.然后拿到username和password。这里使用的是obtainUsername方法,也就是get方法。

@Nullable
protected String obtainPassword(HttpServletRequest request) {
   return re<p>本文来源gao!%daima.com搞$代*!码$网9</p>quest.getParameter(this.passwordParameter);
}

@Nullable
protected String obtainUsername(HttpServletRequest request) {
   return request.getParameter(this.usernameParameter);
}

由此我们知道了Spring Security中是通过get方法来拿到参数,所以在进行前后端分离的时候是无法接受JSON数据,处理方法就是自定义一个Filter来继承UsernamePasswordAuthenticationFilter,重写attemptAuthentication方法,然后创建一个Filter实例写好登陆成功和失败的逻辑处理,在HttpSecurity参数的configure中通过addFilterAt来替换Spring Security官方提供的过滤器。
3.创建一个UsernamePasswordAuthenticationToken 实例。
4.设置Details,在这里关键的是在WebAuthenticationDetails类中记录了用户的remoteAddress和sessionId。

public WebAuthenticationDetails(HttpServletRequest request) {
   this.remoteAddress = request.getRemoteAddr();
   HttpSession session = request.getSession(false);
   this.sessionId = (session != null) ? session.getId() : null;
}

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Spring Security登陆流程讲解
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址