Building microservices from scratch: annotation function integration and password encryptor adjustment

Posted by laurajohn89 on Thu, 10 Feb 2022 02:15:54 +0100

Annotation function integration

So far, there are a few customized annotations on the entry class of each micro service module, such as the entry class of Elsa server demo module:

@EnableDiscoveryClient
@SpringBootApplication
@EnableGlobalMethodSecurity(prePostEnabled = true)	//Annotation indicating permission to open Spring Cloud Security
@EnableElsaAuthExceptionHandler
@EnableFeignClients	//Enable Feign Client function
@EnableElsaOauth2FeignClient
@EnableElsaServerProtect
public class ElsaServerDemoApp{
    public static void main(String[] args) {
        SpringApplication.run(ElsaServerDemoApp.class, args);
    }
}

Three user-defined entry annotations are used to:

  • @EnableElsaServerProtect enables microservice protection to prevent clients from directly requesting microservices by bypassing the gateway
  • @EnableElsaOauth2FeignClient: open the Feign request with token to avoid 401 exceptions in the internal call of microservice
  • @EnableElsaAuthExceptionHandler, authentication type exception translation

These three functions are necessary functions for microservice providers, so we can define an annotation to integrate these three functions.

selector registration

Because these three annotations register the configuration class in the IOC container through the @ Enable type annotation, what we need to do now is to register these three configuration classes in the IOC container at one time. In Spring, to register multiple classes, you can use the method of selector.
In the ELSA common module at com elsa. Create a new selector package under common, and then create ElsaCloudApplicationSelector under the package:

public class ElsaCloudApplicationSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{
                ElsaAuthExceptionConfigure.class.getName(),
                ElsaOAuth2FeignConfigure.class.getName(),
                ElsaServerProtectConfigure.class.getName()
        };
    }
}

Through the selectImports method, we imported elsaauthexeptionconfigure, elsaouth2feignconfigure and ElsaServerProtectConfigure at one time.
For the above code to take effect, we also need to register ElsaCloudApplicationSelector in the IOC container. As before, we can implement it by annotation.

In the ELSA common module at com elsa. common. Create a new ElsaCloudApplication annotation under the annotation path:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(ElsaCloudApplicationSelector.class)
public @interface ElsaCloudApplication {

}

The three annotations on Elsa auth, Elsa server system and Elsa server demo entry classes can be replaced by @ ElsaCloudApplication:

elsa-auth

@EnableDiscoveryClient
@SpringBootApplication
//@EnableElsaAuthExceptionHandler
//@EnableElsaServerProtect
@ElsaCloudApplication
public class ElsaAuthApp 
{
    public static void main(String[] args) {
        SpringApplication.run(ElsaAuthApp.class, args);
    }
}

elsa-server-system

@EnableDiscoveryClient
@SpringBootApplication
@EnableGlobalMethodSecurity(prePostEnabled = true)	//Annotation indicating permission to open Spring Cloud Security
//@EnableElsaAuthExceptionHandler
//@EnableElsaServerProtect
@ElsaCloudApplication
public class ElsaServerSystemApp {
    public static void main(String[] args) {
        SpringApplication.run(ElsaServerSystemApp.class, args);
    }
}

elsa-server-demo

@EnableDiscoveryClient
@SpringBootApplication
@EnableGlobalMethodSecurity(prePostEnabled = true)	//Annotation indicating permission to open Spring Cloud Security
//@EnableElsaAuthExceptionHandler
@EnableFeignClients	//Enable Feign Client function
//@EnableElsaOauth2FeignClient
//@EnableElsaServerProtect
@ElsaCloudApplication
public class ElsaServerDemoApp{
    public static void main(String[] args) {
        SpringApplication.run(ElsaServerDemoApp.class, args);
    }
}

PostMan test

All requests through the gateway are normal





Password encryptor adjustment

When building the authentication server, a passwordencoder Bean of BCryptPasswordEncoder type is registered in ElsaSecurityConfigure, the Web security configuration class of Elsa auth module. But in fact, this password encryptor needs to be used not only in Elsa auth, but also in Elsa server system, such as adding users, changing passwords and other services, so this Bean is suitable to be defined in Elsa common general module.
Modify ElsaServerProtectConfigure of Elsa common module and add the following code

public class ElsaServerProtectConfigure implements 
WebMvcConfigurer {

	......

    @Bean
    @ConditionalOnMissingBean(value = PasswordEncoder.class)
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
	......

}

@ConditionalOnMissingBean(value = PasswordEncoder.class) annotation indicates that when there is no Bean of PasswordEncoder type in the IOC container, BCryptPasswordEncoder will be registered in the IOC container.
Modify ElsaSecurityConfigure code of Elsa auth module:

@Order(2)	// Increase the priority of the filter chain because the priority of ElsaResourceServerConfigure is 3
@EnableWebSecurity	// Enable Web related security configuration
public class ElsaSecurityConfigure extends WebSecurityConfigurerAdapter {
	
	......

   @Autowired
   private PasswordEncoder passwordEncoder;
    
	......

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder);
    }
}

Restart Elsa auth project and test and certification is successful.

Source download

Source address: Annotation function integration and password encryptor adjustment

Topics: Spring Cloud Microservices