micronautmicronaut-security

Does Micronaut have a built-in login form like spring boot does?


Does Micronaut have an equivalent to the spring "formLogin" feature?

When creating a spring boot application, we can add a method (bean) to a @Configuration annotated class like

@Bean 
public SecurityFilterChain sfc(HttpSecurity s) { 
   return s.csrf()
     .disable()
     .authorizeRequests().antMatchers("/**").authenticated()
     .formLogin()
     .build(); 
}

And that is enough to have my app secured, and the password will be checked against the environment variables SPRING_SECURITY_USER_{NAME,PASSWORD}. This makes it very easy to add security to an application.

Was curious if the Micronaut project had a similar way to get up and running with a couple lines of code.

Edit: it also displays this form using bootstrap css: https://github.com/spring-projects/spring-security/blob/main/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLoginPageGeneratingFilter.java


Solution

  • All you got to do in Micronaut is to go through the steps described in the Micronaut Security Guide.

    TL;DR

    The Spring Boot feature you're mentioning is not available in Micronaut. But the following easy steps will provide to get there as close as possible.

    Mainly that's following these steps:

    annotationProcessor("io.micronaut.security:micronaut-security-annotations")
    implementation("io.micronaut.security:micronaut-security-jwt")
    
    micronaut:
       security:
          enabled: true # true is the default value
    

    You can either secure your controller by using the @Secured annotation or define intercepted urls in your application.yml

    micronaut:
      security:
        basic-auth:
          enabled: true # enabled basic authentication
        intercept-url-map:
          - pattern: /**
            access:
              - isAuthenticated()
    

    Then you write a simple authentication provider that does the login verifcation.

    import io.micronaut.context.annotation.Requires;
    import io.micronaut.http.HttpRequest;
    import io.micronaut.security.authentication.AuthenticationProvider;
    import io.micronaut.security.authentication.AuthenticationRequest;
    import io.micronaut.security.authentication.AuthenticationResponse;
    import jakarta.inject.Singleton;
    import org.reactivestreams.Publisher;
    import reactor.core.publisher.Mono;
    @Singleton
    public class AuthenticationProviderUserPassword implements AuthenticationProvider {
    
        @Override
        public Publisher<AuthenticationResponse> authenticate(HttpRequest<?> httpRequest, AuthenticationRequest<?, ?> authenticationRequest) {
            return Mono.<AuthenticationResponse>create(emitter -> {
                if (authenticationRequest.getIdentity().equals(System.getenv("YOUR-USER")) && authenticationRequest.getSecret().equals(System.getenv("YOUR-PWD"))) {
                    emitter.success(AuthenticationResponse.success("user"));
                } else {
                    emitter.error(AuthenticationResponse.exception());
                }
            });
        }
    }
    

    That does the job for a good start.