Trying to protect the controller with micronaut security using JUnit testing, getting authentication as NULL.
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@MicronautTest
public class ProductCreateTest extends TestContainerFixture {
private BearerAccessRefreshToken bearerAccessRefreshToken = null;
@Inject
@Client("/")
HttpClient client;
private ProductModel productModel;
@Test
@Order(1)
@DisplayName("Should create a JWT token")
void shouldCreateAJwtToken() {
UsernamePasswordCredentials creds = new UsernamePasswordCredentials("admin@local.com", "RockStar.1");
HttpRequest request = HttpRequest.POST("/login", creds);
HttpResponse<BearerAccessRefreshToken> rsp = client.toBlocking().exchange(request, BearerAccessRefreshToken.class);
bearerAccessRefreshToken = rsp.body();
}
@Test
@Order(2)
@DisplayName("Should create the product")
void shouldCreateTheProduct() {
this.productModel = new ProductModel(
null,
Optional.of(true),
Optional.of(false),
"Nike shirt",
"Nike shirt description",
Optional.of(new CategoryModel(new ObjectId().toString(), "Men", "Men")),
Optional.of(new SubCategoryModel(new ObjectId().toString(), "Men", "Men")),
Optional.of(new VendorModel(new ObjectId().toString(), "Men", "Men")),
Optional.of(List.of(new SelectOptionModel("Shirt", "Shirt"))),
Optional.of(false)
);
HttpRequest request = HttpRequest.POST("/product", this.productModel)
.header("Authorization",bearerAccessRefreshToken.getAccessToken());
HttpResponse<ProductModel> rsp = client.toBlocking().exchange(request, ProductModel.class);
var item = rsp.body();
}
}
Authentication Provider
@Singleton
@Requires(env = Environment.TEST)
public record AuthenticationProviderUserPasswordFixture() implements AuthenticationProvider {
@Override
public Publisher<AuthenticationResponse> authenticate(HttpRequest<?> httpRequest, AuthenticationRequest<?, ?> authenticationRequest) {
return Flux.create(emitter -> {
if (authenticationRequest.getIdentity().equals("admin@local.com") && authenticationRequest.getSecret().equals("RockStar.1")) {
emitter.next(AuthenticationResponse.success((String) authenticationRequest.getIdentity(), List.of("roles1", "roles2")));
emitter.complete();
} else {
emitter.error(AuthenticationResponse.exception());
}
}, FluxSink.OverflowStrategy.ERROR);
}
}
Controller defination
@Post
@IRequirement(resourceName = ClaimType.TAG_PRODUCT, permission = {ClaimValue.TAG_OWNER,ClaimValue.TAG_CREATOR,ClaimValue.TAG_MAINTAINER })
Mono<MutableHttpResponse<?>> post(@Body @Valid ProductModel model);
Security Rule
@Singleton
public class AuthorityHandler implements SecurityRule {
@Override
public Publisher<SecurityRuleResult> check(HttpRequest<?> request, @Nullable RouteMatch<?> routeMatch, @Nullable Authentication authentication) {
if (routeMatch instanceof MethodBasedRouteMatch methodBasedRouteMatch) {
if (methodBasedRouteMatch.hasAnnotation(IRequirement.class)) {
AnnotationValue<IRequirement> requiredPermissionAnnotation = methodBasedRouteMatch.getAnnotation(IRequirement.class);
Optional<String> resourceIdName = requiredPermissionAnnotation.stringValue( "resourceName");
String[] permissions = requiredPermissionAnnotation.stringValues("permission");
if (permissions.length > 0 && resourceIdName.isPresent() && authentication != null) {
Map<String, Object> identityClaims = authentication.getAttributes();
if (Arrays.stream(permissions).anyMatch(element -> identityClaims.containsValue(element)))
return Mono.just(SecurityRuleResult.ALLOWED);
else
return Mono.just(SecurityRuleResult.REJECTED);
}
}
}
return Mono.just(SecurityRuleResult.UNKNOWN);
}
}
In the security rule the check method The Authentication authentication
is null. However, from the Authentication Provider, I have successful authentication.