It's done! OAuth2 uses the verification code for authorization

Now the verification code login has become the mainstream login method of many applications, but for OAuth2 authorization, the processing of mobile phone number verification code and user authentication is very cumbersome, but many students don't know how to access.

Seriously study fat brother Spring Security OAuth2 column Everyone will know one thing. OAuth2 in fact, no matter how the resource owner authenticates, as long as the resource owner authenticates in the authorization link, it doesn't matter whether you are a verification code, account secret, or even fingerprint iris.

Id Server implementation

Therefore, Pang seems to have found a way to connect the verification code to the Id Server. Previously, Pang opened a login extension package of Spring Security spring-security-login-extension , one key access authentication code login and applet login can be realized by using this. So I transformed it and successfully realized this function. See the effect below:

Compared with before, users can choose account secret login or mobile authentication code login in the authorization process.

❝ here you can make some changes. Can all kinds of verification code login be compatible?

General principle

This needs to be realized by front and back-end cooperation.

back-end

The core is still the usage of the expansion package. Add LoginFilterSecurityConfigurer configuration to HttpSecurity. I have changed it here, which is different from that in the original package. JWT cannot be returned after successful login here. It needs to be consistent with the account secret login. The core code is as follows:

httpSecurity.apply(new LoginFilterSecurityConfigurer<>())
     // Mobile number verification code login simulation
         .captchaLogin(captchaLoginConfigurer ->
    // Verification code verification 1 is configured here with the highest priority, and 2 can be registered as a Spring Bean without configuration
                 captchaLoginConfigurer.captchaService(this::verifyCaptchaMock)
   // Query the user useressentials according to the mobile phone number. 1 configure the highest priority here. 2 register as Spring Bean, which is free of configuration
                          .captchaUserDetailsService(this::loadUserByPhoneMock)
                          // The two logins are consistent
                          .successHandler(loginAuthenticationSuccessHandler)
                          // The two logins are consistent
                          .failureHandler(authenticationFailureHandler);
copy

loadUserByPhoneMock simulates CaptchaUserDetailsService interface and loads UserDetails according to mobile phone number:

private UserDetails loadUserByPhoneMock(String phone) throws UsernameNotFoundException {
    return  // user name
          User.withUsername(phone)
            // password
              .password("password")              .passwordEncoder(PasswordEncoderFactories.createDelegatingPasswordEncoder()::encode)
              .roles("user", "mobile")
              .build();
        }
copy

verifyCaptchaMock is a simulation of CaptchaService, the verification code verification logic interface. It is written as 1234 here. In actual development, it should be implemented with cache, which is stored in the cache from the code sending interface, and the cache interface is called in CaptchaService to take out the verification code for verification:

private boolean verifyCaptchaMock(String phone, String code) {
    //todo implements its own cache verification logic
            return code.equals("1234");
}
copy

❝ the interface for sending the verification code can be realized freely. There is no need to define the specification here. Just remember to access the cache. You can see the verification code This one.

front end

The front end only needs to access a login page that can switch the login mode. Then match the verification code login interface and the sending verification code interface. The authorization login page is oauth2_login.html, through its controller, Pangge even added a switch enableCaptchaLogin to decide whether to use the verification code authentication method.

@GetMapping("/login")
public String oauth2LoginPage(Model model,
                         @CurrentSecurityContext(expression = "authentication")
                          Authentication authentication,
                         @Value("${spring.security.oauth2.server.login.captcha.enabled:true}")
                                   boolean enableCaptchaLogin,
                 @RequestAttribute(name = "org.springframework.security.web.csrf.CsrfToken", required = false)
                                   CsrfToken csrfToken) {

     if (!(authentication instanceof AnonymousAuthenticationToken)){
         return "redirect:/";
     }
     if (csrfToken != null) {
         model.addAttribute("_csrfToken", csrfToken);
     }
     SystemSettings systemSettings = new SystemSettings();
     model.addAttribute("enableCaptchaLogin",enableCaptchaLogin);
     model.addAttribute("systemSettings", systemSettings);
     return "oauth2_login";
}
copy

JS processing related to front end and verification code:

        if ([[${enableCaptchaLogin}]]){
            form.on('submit(mobile-login)', function (data) {
                let loader = layer.load();
                let btn = button.load({elem: '.login'});
                $.ajax({
                    url: '/login/captcha',
                    data: data.field,
                    type: "post",
                    dataType: 'json',
                    success: function (result) {
                        layer.close(loader);
                        btn.stop(function () {
                            if (result.code === 200) {
                                popup.success(result.msg, function () {
                                    location.href = result.data.targetUrl;
                                })
                            } else if (result.code === 401) {
                                popup.failure(result.msg);
                            }
                        })
                    }
                });
                return false;
            });

            $('#captcha-btn').click(function (){
                //TODO is connected to the verification code interface here
                popup.success('Verification code sent');
            })
        }

copy

summary

OAuth2 uses authentication code for authorization, which is applicable to all demos provided by Id Server. If you are interested, you can get the latest verification code authorization code from the following warehouse address and remember to give it to Star:

https://github.com/NotFound403/id-server
copy

In addition, someone asked about the relationship between Id Server and Pangge's Spring Security OAuth2 column. Id Server is an open source project. The underlying logic support comes from the analysis of Spring Authorization Server. Mastering the knowledge of the column can help you customize the transformation of Id Server. The goal of Id Server is to build a production available OAuth2 authorization server and reduce the learning and use cost of OAuth2. I hope you can support it more.

Posted by respecttheplayer on Sun, 22 May 2022 05:41:53 +0300