package com.jd.lightapplication.security;

import cn.hutool.core.util.StrUtil;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MobileAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
    public static final String WU_FORM_MOBILE_KEY = "mobile";
    private String mobileParameter = "phone";
    private boolean postOnly = true;  //只处理Post请求。

    //请求的匹配器。
    public MobileAuthenticationFilter() {
        super(new AntPathRequestMatcher("/login/mobile", "POST"));
    }

    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());
        } else {
            //取出手机号
            String mobile = this.obtainMobile(request);
            if (mobile == null) {
                mobile = "";
            }
            //去除空格
            mobile = mobile.trim();
            //这里封装未认证的Token
            MobileAuthenticationToken authRequest = new MobileAuthenticationToken(mobile);
            //将请求信息也放入到Token中。
            this.setDetails(request, authRequest);
			//首先进入方法这里会找到我们自己写的SmsCodeAuthenticationProvider.
            //最后将结果放回到这里之后，经过AbstractAuthenticationProcessingFilter，这个抽象类的doFilter，然后调用处理器。成功调用成功处理器，失败调用失败处理器。
            return this.getAuthenticationManager().authenticate(authRequest);
        }
    }

    /**
     * 获取手机号的方法
     * @param request
     * @return
     */
    protected String obtainMobile(HttpServletRequest request) {
        String phone = request.getParameter(this.mobileParameter);
        if(StrUtil.isBlank(phone)){
            phone = request.getAttribute(this.mobileParameter).toString();
        }
        return phone;
    }
    //将请求信息也放入到Token中。
    protected void setDetails(HttpServletRequest request, MobileAuthenticationToken authRequest) {
        authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
    }

    public void setMobileParameter(String mobileParameter) {
        Assert.hasText(mobileParameter, "mobile parameter must not be empty or null");
        this.mobileParameter = mobileParameter;
    }

    public void setPostOnly(boolean postOnly) {
        this.postOnly = postOnly;
    }

    public final String mobileParameter() {
        return this.mobileParameter;
    }
}

