Spring Security Oauth2.0 实现短信验证码登录示例

下面就为您详细讲解“Spring Security Oauth2.0 实现短信验证码登录示例”的完整攻略。

准备工作

  1. 搭建Spring Boot环境
  2. 添加Spring Security依赖
  3. 添加Spring Security Oauth2依赖
  4. 添加MySQL数据库及驱动依赖
  5. 创建用户表、客户端表、验证码表

示例1:实现短信验证码登录

  1. 自定义继承于AbstractUserDetailsAuthenticationProvider的短信验证码验证器SmsCodeAuthenticationProvider,实现自定义的验证逻辑。
@Component
public class SmsCodeAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        // 校验用户信息
    }

    @Override
    protected UserDetails retrieveUser(String mobile, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        UserDetails userDetails = userDetailsService.loadUserByUsername(mobile);
        // 校验短信验证码
        return userDetails;
    }
}
  1. 自定义实现AuthenticationFilter的短信验证码登录认证过滤器SmsCodeAuthenticationFilter,处理短信验证码登录请求,生成UsernamePasswordAuthenticationToken传递给SmsCodeAuthenticationProvider
public class SmsCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    public SmsCodeAuthenticationFilter() {
        super(new AntPathRequestMatcher("/login/sms", "POST"));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        String mobile = request.getParameter("mobile");
        String smsCode = request.getParameter("smsCode");

        SmsCodeAuthenticationToken authRequest = new SmsCodeAuthenticationToken(mobile, smsCode);
        setDetails(request, authRequest);

        AuthenticationManager authenticationManager = getAuthenticationManager();
        return authenticationManager.authenticate(authRequest);
    }

    protected void setDetails(HttpServletRequest request, SmsCodeAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }
}
  1. 在Spring Security的配置类中,注册SmsCodeAuthenticationFilterSmsCodeAuthenticationProvider
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private SmsCodeAuthenticationProvider smsCodeAuthenticationProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/login/sms").permitAll()
                .anyRequest().authenticated()
                .and()
            .addFilterBefore(smsCodeAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
            .formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/login")
                .usernameParameter("username")
                .passwordParameter("password")
                .permitAll()
                .and()
            .logout()
                .logoutSuccessUrl("/")
                .permitAll()
                .and()
            .csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(smsCodeAuthenticationProvider);
    }

    @Bean
    public SmsCodeAuthenticationFilter smsCodeAuthenticationFilter() throws Exception {
        SmsCodeAuthenticationFilter smsCodeAuthenticationFilter = new SmsCodeAuthenticationFilter();
        smsCodeAuthenticationFilter.setAuthenticationManager(authenticationManagerBean());
        smsCodeAuthenticationFilter.setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler("/"));
        smsCodeAuthenticationFilter.setAuthenticationFailureHandler(new SimpleUrlAuthenticationFailureHandler("/login?error"));
        return smsCodeAuthenticationFilter;
    }
}
  1. 在前端页面中添加短信验证码登录的链接和表单。
<a href="#" onclick="sendSmsCode()">获取验证码</a>
<form id="smsLoginForm" action="/login/sms" method="post">
    <input type="text" name="mobile" placeholder="请输入手机号" required />
    <input type="text" name="smsCode" placeholder="请输入验证码" required />
    <input type="submit" value="提交" />
</form>

示例2:实现短信验证码登录和密码登录的多重验证

在上面添加短信验证码登录的基础上,我们可以进一步实现多重验证的需求,例如需要同时验证密码和短信验证码。

  1. 在Spring Security的配置类中,注册一个新的AuthenticationProvider,用于处理多重验证的逻辑。
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(smsCodeAuthenticationProvider)
                .authenticationProvider(new MultiAuthenticationProvider(Arrays.asList(smsCodeAuthenticationProvider, daoAuthenticationProvider())));
    }

    private DaoAuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
        return daoAuthenticationProvider;
    }
  1. 在自定义MultiAuthenticationProvider中按需调用已注册的AuthenticationProvider进行验证。
public class MultiAuthenticationProvider implements AuthenticationProvider {

    private List<AuthenticationProvider> providers;

    public MultiAuthenticationProvider(List<AuthenticationProvider> providers) {
        this.providers = providers;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        AuthenticationException lastException = null;
        for (AuthenticationProvider provider : providers) {
            try {
                return provider.authenticate(authentication);
            } catch (AuthenticationException e) {
                lastException = e;
            }
        }
        throw lastException;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return providers.stream().anyMatch(p -> p.supports(authentication));
    }
}
  1. 在前端页面中添加密码登录的表单。
<form id="passwordLoginForm" action="/login" method="post">
    <input type="text" name="username" placeholder="请输入用户名" required />
    <input type="password" name="password" placeholder="请输入密码" required />
    <input type="submit" value="登录" />
</form>
  1. 在Spring Security的配置类中排除密码登录的请求地址。
        http
            .authorizeRequests()
                .antMatchers("/login/sms").permitAll()
                .antMatchers("/login").not().hasAnyAuthority(Authority.ADMIN.name(), Authority.USER.name())
                .anyRequest().authenticated()
                .and()
            .addFilterBefore(smsCodeAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
            .formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/login")
                .usernameParameter("username")
                .passwordParameter("password")
                .permitAll()
                .and()
            .logout()
                .logoutSuccessUrl("/")
                .permitAll()
                .and()
            .csrf().disable();

以上就是“Spring Security Oauth2.0 实现短信验证码登录示例”的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security Oauth2.0 实现短信验证码登录示例 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • boot-admin开源项目中有关后端参数校验的最佳实践

    我们在项目开发中,经常会对一些参数进行校验,比如非空校验、长度校验,以及定制的业务校验规则等,如果使用if/else语句来对请求的每一个参数一一校验,就会出现大量与业务逻辑无关的代码,繁重不堪且繁琐的校验,会大大降低我们的工作效率,而且准确性也无法保证。为保证数据的正确性、完整性,前后端都需要进行数据检验。本文对开源 boot-admin 项目的后端校验实践…

    Java 2023年5月7日
    00
  • SpringBoot整合SQLite数据库全过程

    下面我将为您详细讲解SpringBoot整合SQLite数据库的全过程,包括以下几个步骤: 导入SQLite依赖 配置SQLite数据源 创建实体类 创建DAO接口 创建Service层 创建Controller层 示例演示 1.导入SQLite依赖 在pom.xml文件中添加以下依赖: <dependency> <groupId>o…

    Java 2023年5月20日
    00
  • 举例讲解Java中Piped管道输入输出流的线程通信控制

    讲解Java中Piped管道输入输出流的线程通信控制的攻略如下: 什么是Piped管道输入输出流 Java中的Piped输入输出流是一种基于管道(pipe)的流方式。管道是一种常见的进程间通信(IPC)的方式。Piped输入输出流提供了一个可以连接线程的管道,其中一个线程通过写入实现输出流的数据传递,而另一个线程通过读取实现输入流的数据读取。 Piped的使…

    Java 2023年5月26日
    00
  • Java Apache Commons报错“ConversionException”的原因与解决方法

    当使用Java的Apache Commons类库时,可能会遇到“ConfigurationException”错误。这个错误通常由以下原因之一起: 配置文件错误:如果配置文件错误,则可能会出现此错误。在这种情况下,需要检查配置文件以解决此问题。 配置项缺失:如果配置项缺失,则可能会出现此错误。在这种情况下,需要检查配置项以解决此问题。 以下是两个实例: 例1…

    Java 2023年5月5日
    00
  • IDEA项目maven project没有出现plugins和Dependencies问题

    当在IntelliJ IDEA中创建Maven项目时,有时可能会遇到plugins和dependencies标签未自动生成的问题。此时,可以按照以下攻略进行解决。 在pom.xml中添加plugins和dependencies标签 在pom.xml文件中手动添加plugins和dependencies标签可以解决此问题。我们可以使用以下代码: <plu…

    Java 2023年5月19日
    00
  • 用JavaScript实现 铁甲无敌奖门人 “开口中”猜数游戏

    下面是用JavaScript实现「铁甲无敌奖门人“开口中”猜数游戏」的完整攻略。 游戏规则 该游戏分为两个角色:猜数者和奖门人。在游戏开始时,奖门人会先随机设定一个数(一般为 1 到 100 之间的整数),并说出自己设定的数是在 1 到 100 之间。然后,猜数者可以轮流猜测这个数字,而奖门人将回答「大了」、「小了」或者「猜对了」。如果猜数者猜对了,游戏结束…

    Java 2023年6月15日
    00
  • Java中判断字符串是否相等的实现

    下面是“Java中判断字符串是否相等的实现”的完整攻略。 一、Java中字符串的比较 Java中字符串比较的基本原理是比较字符串的内容是否相等。由于String类型是一个final类,所以String对象在被创建后就不能再被修改了,因此在Java当中比较两个字符串的时候,不能使用”==”运算符。应该使用equals()方法或equalsIgnoreCase(…

    Java 2023年5月26日
    00
  • Java日常练习题,每天进步一点点(40)

    下面是Java日常练习题的完整攻略: 1. 确定目标 我们的目标是通过做Java练习题来提高自己的编程能力,每天进步一点点。 2. 获取练习题 可以通过互联网上的Java编程练习网站,如Java编程练习网站等获取练习题。 3. 分析题目 在开始解题之前,请认真阅读题目并分析,确定题目的输入、输出、边界条件和算法思路。 4. 用Java代码实现 在分析完题目后…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部