当前位置: 首页 > news >正文

spring boot security 自定义AuthenticationProvider

spring boot security 自定义AuthenticationProvider

基于 spring boot 3.x

场景实现 手机验证码登陆

实现

CaptureCodeAuthenticationFilter

public class CaptureCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    private static final String DEFAULT_LOGIN_URL = "/capture/login";

    private static final String DEFAULT_PHONE_NAME = "phone";
    private static final String DEFAULT_CODE_NAME = "code";

    private String codeParamName = DEFAULT_CODE_NAME;

    private String phoneParamName = DEFAULT_PHONE_NAME;

    public CaptureCodeAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(DEFAULT_LOGIN_URL, authenticationManager);
    }

    public CaptureCodeAuthenticationFilter(String defaultFilterProcessesUrl, AuthenticationManager authenticationManager) {
        super(defaultFilterProcessesUrl, authenticationManager);

    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        if (!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }
        String phone = obtainPhone(request);
        phone = (phone != null) ? phone.trim() : "";
        String code = obtainCaptureCode(request);
        code = (code != null) ? code : "";
        CaptureCodeAuthenticationToken token = new CaptureCodeAuthenticationToken(phone, code);
        return this.getAuthenticationManager().authenticate(token);
    }


    protected String obtainCaptureCode(HttpServletRequest request) {
        return request.getParameter(this.codeParamName);
    }


    protected String obtainPhone(HttpServletRequest request) {
        return request.getParameter(this.phoneParamName);
    }
}

CaptureCodeAuthenticationToken

public class CaptureCodeAuthenticationToken extends UsernamePasswordAuthenticationToken {
    public CaptureCodeAuthenticationToken(Object principal, Object credentials) {
        super(principal, credentials);
    }
}

CaptureCodeAuthenticationProvider

public class CaptureCodeAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

    @Override
    public boolean supports(Class<?> authentication) {
        return (CaptureCodeAuthenticationToken.class.isAssignableFrom(authentication));
    }

    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        if (authentication.getPrincipal()==null){
            throw new BadCredentialsException("Bad credentials "+ authentication.getPrincipal().toString());
        }
        if (authentication.getCredentials()==null){
            throw new BadCredentialsException("Bad credentials "+ authentication.getPrincipal().toString());
        }
    }

    @Override
    protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        CaptureCodeAuthenticationToken token = (CaptureCodeAuthenticationToken) authentication;
        if (!token.getPrincipal().equals("tom")){
            throw new UsernameNotFoundException("username not fund!");
        }
        UserDetails user = User.withUsername("tom")
                .password("tom")
                .build();
        return user;
    }


}

配置 DefaultSecurityConfig

@Configuration
@EnableWebSecurity
public class DefaultSecurityConfig {

    @Autowired
    private ObjectMapper objectMapper;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(request -> request.anyRequest().authenticated());
        http.formLogin(Customizer.withDefaults());
        http.csrf(AbstractHttpConfigurer::disable);
        http.addFilterBefore(captureCodeAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }

    public CaptureCodeAuthenticationFilter captureCodeAuthenticationFilter() {
        ProviderManager providerManager = new ProviderManager(new CaptureCodeAuthenticationProvider());
        CaptureCodeAuthenticationFilter filter =
                new CaptureCodeAuthenticationFilter(providerManager);
        filter.setAuthenticationSuccessHandler((request, response, authentication) -> {
            response.setStatus(HttpServletResponse.SC_OK);
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            response.getWriter().write(objectMapper.writeValueAsString(Result.ok("认证成功")));
            response.getWriter().flush();
        });
        filter.setAuthenticationFailureHandler((request, response, exception) -> {
            response.setStatus(HttpServletResponse.SC_OK);
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            response.getWriter().write(objectMapper.writeValueAsString(Result.ok("认证失败")));
            response.getWriter().flush();
        });
        return filter;
    }

    @Bean
    public UserDetailsService users(PasswordEncoder passwordEncoder) {
        UserDetails user = User.withUsername("admin")
                .password(passwordEncoder.encode("admin"))
                .build();
        return new InMemoryUserDetailsManager(user);
    }


    @Bean
    public PasswordEncoder encoder() {
        return new BCryptPasswordEncoder();
    }

}

相关文章:

  • 软考 系统架构设计师系列知识点之边缘计算(5)
  • 力扣138:随机链表的复制
  • CHATGPT----自然辩证法分析
  • 【Hadoop实战】Hadoop指标系统V2分析
  • Spring Boot 3.0正式发布及新特性解读
  • 文件的想对
  • 竞赛选题 深度学习疲劳驾驶检测 opencv python
  • vue+iView实现下载zip文件导出多个excel表格
  • WebSphere Liberty 8.5.5.9 (二)
  • Unity中关于Lerp()方法的使用
  • k8s存储
  • Python与ArcGIS系列(二)获取地图文档
  • 【SpringBoot】手写模拟SpringBoot核心流程
  • 超强C语言跨年烟花代码,精美无比,附源码分步解析
  • No source control providers registered
  • 小程序 打开方式 页面效果 表单页面 点击跳到详情页 图标 获取后台数据 进行页面渲染
  • 智安网络|探索人机交互的未来:自然语言处理的前沿技术
  • C# wpf 实现任意控件(包括窗口)更多拖动功能
  • 【Spring生命周期核心底层源码之剖析】
  • C复习-结构struct+bit field+union
  • 蒲慕明院士:好的科普应以“质疑、讨论公众关切的科学问题”为切入点
  • 男子聚餐饮酒后身亡,同桌3人被判赔偿近20万元
  • 打造信息消费新场景、新体验,上海信息消费节开幕
  • 哈马斯与以色列在多哈举行新一轮加沙停火谈判
  • 中国首艘海洋级智能科考船“同济”号试航成功,可搭载水下遥控机器人
  • 六连板成飞集成:航空零部件业务收入占比为1.74%,市场环境没有重大调整