package cn.reghao.oss.console.account.security.form;

import cn.reghao.oss.console.account.model.dto.AccountLoginDto;
import cn.reghao.oss.console.account.service.AccountAuthService;
import cn.reghao.jutil.web.ServletUtil;
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 javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 账号密码登录 filter
 * 替换 UsernamePasswordAuthenticationFilter，用于认证用户，匹配指定 URL 才会进行处理
 *
 * @author reghao
 * @date 2022-07-06 15:55:59
 */
public class AccountAuthFilter extends AbstractAuthenticationProcessingFilter {
    private final AccountAuthService accountAuthService;

    public AccountAuthFilter(String authUrl, String httpMethod, AccountAuthService accountAuthService) {
        super(new AntPathRequestMatcher(authUrl, httpMethod));
        this.accountAuthService = accountAuthService;
    }

    /**
     * 构造 Authentication 对象
     * 参照 UsernamePasswordAuthenticationFilter
     *
     * @param
     * @return
     * @date 2020-05-06 上午11:16
     */
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, IOException, ServletException {
        // json payload 中的 username 和 password 参数
        AccountLoginDto accountLoginDto = (AccountLoginDto) ServletUtil.getBody(request, AccountLoginDto.class);
        AccountAuthToken preAuthToken = accountAuthService.getPreAuthentication(accountLoginDto);
        // 调用 UserAuthProvider.authenticate()
        return this.getAuthenticationManager().authenticate(preAuthToken);
    }
}
