zeromemos
最好的学习方法就是输出所学的知识

SpringSecurity替换UsernamePasswordAuthenticationFilter过滤器实现登录

SpringSecurity可以通过配置WebSecurityConfigurerAdapter中的configure,替换UsernamePasswordAuthenticationFilter过滤器实现前后端分离登录


//启用formLogin
        http.formLogin().and()
                //加入登录认证过滤器
                .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
                //替换原来的登录方法
                .addFilterAt(loginFilter(), UsernamePasswordAuthenticationFilter.class);

jwtAuthenticationTokenFilter是每次访问时的登录认证检查,loginFilter()是自定义的登录过滤器,需要继承UsernamePasswordAuthenticationFilter。

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

public class LoginFilter extends UsernamePasswordAuthenticationFilter {

    //重写登录认证
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        //判断是否为POST请求
        if (!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }

        //判断是否为json格式请求类型
        if (request.getContentType().equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)) {

            //从json数据中获取用户输入用户名和密码进行认证
            try {
                Map<String, String> userInfo = new ObjectMapper().readValue(request.getInputStream(), Map.class);
                String username = userInfo.get(getUsernameParameter());
                String password = userInfo.get(getPasswordParameter());
                UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
                this.setDetails(request, authRequest);
                return this.getAuthenticationManager().authenticate(authRequest);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        return super.attemptAuthentication(request, response);
    }
}

配置loginFilter的其他内容,比如加入AuthenticationManager,配置认证成功处理器和认证失败处理器。

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public LoginFilter loginFilter() throws Exception {
        LoginFilter loginFilter = new LoginFilter();
        loginFilter.setAuthenticationManager(authenticationManagerBean());
        //认证成功处理
        loginFilter.setAuthenticationSuccessHandler(new MyAuthenticationSuccessHandler(redisTemplate));
        //认证失败处理
        loginFilter.setAuthenticationFailureHandler((request, response, exception) -> {
            ResponseJsonUtils.responseJson(response, MyResult.error().message("登录失败"));
        });
        return loginFilter;
    }

ResponseJsonUtils是给前端返回JSON信息的工具类,setAuthenticationSuccessHandler是设置登录成功处理器,setAuthenticationFailureHandler是登录失败处理器。

评论区

关于我们

本站主要用于记录个人学习笔记,网站开发中,如需以前站内资料请加QQ群272473835索取。注册账号仅提供回帖功能,可不注册!

微信公众号