没有针对该问题的内置解决方案,但有多种方法可以用少量代码实现您想要的。
解决方案№1:
如果您需要多个登录端点,请创建自定义 AuthenticationRequest.class 和 LoginController.class:
public class AuthenticationRequestForEntityA extends UsernamePasswordCredentials { ... }
public class AuthenticationRequestForEntityB extends UsernamePasswordCredentials { ... }
在您的自定义LoginController 中,将默认UsernamePasswordCredentials 替换为您的特定AuthenticationRequestForEntityA 或AuthenticationRequestForEntityB,然后复制粘贴原始LoginController.class 中的其余代码:
@Consumes({MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON})
@Post
public Single<MutableHttpResponse<?>> login(@Valid @Body AuthenticationRequestForEntityA usernamePasswordCredentials, HttpRequest<?> request) {
Flowable<AuthenticationResponse> authenticationResponseFlowable = Flowable.fromPublisher(authenticator.authenticate(request, usernamePasswordCredentials));
...
然后在您的身份验证提供程序中:
public class AuthenticationProviderA implements AuthenticationProvider {
@Override
public Publisher<AuthenticationResponse> authenticate(@Nullable HttpRequest<?> httpRequest, AuthenticationRequest<?, ?> authenticationRequest) {
if (authenticationRequest instanceof AuthenticationRequestForEntityA) {
return authenticate(authenticationRequest);
} else {
// return empty
}
}
}
public class AuthenticationProviderB implements AuthenticationProvider {
@Override
public Publisher<AuthenticationResponse> authenticate(@Nullable HttpRequest<?> httpRequest, AuthenticationRequest<?, ?> authenticationRequest) {
if (authenticationRequest instanceof AuthenticationRequestForEntityB) {
return authenticate(authenticationRequest);
} else {
// return empty
}
}
}
解决方案№2:创建基于自定义路由的AuthenticationProvider
由于HttpRequest 在AuthenticationProvider 中作为输入参数可用,您可以简单地根据httpRequest 路径或查询参数属性进行身份验证。
为了使代码更简洁,您可以创建自己的RouteBasedAuthenticationProvider 接口:
public interface RequestBasedAuthenticationProvider extends AuthenticationProvider {
/**
You can check the request path or request parameter or whatever
*/
boolean supports(HttpRequest<?> request);
}
然后在 Micronaut AuthenticationProvider:
@Context
public class AppAuthenticationProvider implements AuthenticationProvider {
private final Collection<RequestBasedAuthenticationProvider> providers;
constructor(...) {...}
@Override
public Publisher<AuthenticationResponse> authenticate(@Nullable HttpRequest<?> httpRequest, AuthenticationRequest<?, ?> authenticationRequest) {
return providers.stream()
.filter(provider -> provider.supports(httpRequest))
.findFirst()
.orElseThrow(//Throw provider not found error)
.authenticate(httpRequest, authenticationRequest);
}
}