Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Imperative AuthenticationProvider and Reactive AuthenticationProvider #1526

Merged
merged 40 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
0ea1959
add BlockingAuthenticationProvider
sdelamo Dec 7, 2023
6420364
Implementation, tests, and docs.
jeremyg484 Dec 11, 2023
c76773e
Merge branch 'master' into blocking-authentication-provider
sdelamo Dec 12, 2023
70a3a90
BlockingAuthenticationProvider implements Named
sdelamo Dec 12, 2023
792dc08
split docs
sdelamo Dec 12, 2023
d0b0647
add multilanguage snippet
sdelamo Dec 12, 2023
278a68a
remove import
sdelamo Dec 12, 2023
03ddaf3
revert use class again
sdelamo Dec 12, 2023
758afe2
Merge branch 'master' into blocking-authentication-provider
sdelamo Dec 12, 2023
74337d4
Blocking authentication provider impr (#1532)
sdelamo Dec 12, 2023
3251149
Update security/src/main/java/io/micronaut/security/authentication/Bl…
sdelamo Dec 12, 2023
8660cce
rename to ImperativeAuthenticationProvider
sdelamo Dec 13, 2023
e5a6f28
Merge branch 'blocking-authentication-provider-impr' into blocking-au…
sdelamo Dec 13, 2023
c795eaa
deprecated AuthenticationProvider with Publisher
sdelamo Dec 13, 2023
4b689cb
Don’t wrap create ReactiveAuthenticationProvider
sdelamo Dec 13, 2023
4fd4a9b
Update security-oauth2/src/main/java/io/micronaut/security/oauth2/end…
sdelamo Dec 13, 2023
0fff4a6
remove unused constructor
sdelamo Dec 13, 2023
650b456
remove local variables
sdelamo Dec 13, 2023
977db5e
remove mentions to Imperative
sdelamo Dec 13, 2023
385e36c
don’t extend Named
sdelamo Dec 13, 2023
bea22d0
remove ignore
sdelamo Dec 13, 2023
4445f95
remove test
sdelamo Dec 13, 2023
dbbe711
remove @NonNull
sdelamo Dec 13, 2023
c546809
add package-info.java
sdelamo Dec 13, 2023
0de5040
add HttpRequestAuthenticationProvider and HttpRequestReactiveAuthenti…
sdelamo Dec 13, 2023
f9008a2
Update security/src/main/java/io/micronaut/security/authentication/Au…
sdelamo Dec 14, 2023
bc4f0ae
Update security/src/main/java/io/micronaut/security/authentication/pr…
sdelamo Dec 14, 2023
395d89d
Update security/src/main/java/io/micronaut/security/authentication/Au…
sdelamo Dec 14, 2023
8001291
httpRequest with requestContext
sdelamo Dec 14, 2023
c737dd1
annotate with @Indexed
sdelamo Dec 14, 2023
1f237fe
httpRequest with requestContext
sdelamo Dec 14, 2023
07c40af
final AuthenticationProviderAdapter
sdelamo Dec 14, 2023
8c8318d
add generic argument type
sdelamo Dec 14, 2023
e3a5d1b
add default methods
sdelamo Dec 14, 2023
35d8d0a
add new line to package-info.java
sdelamo Dec 14, 2023
c9ce456
sonar: Catch Exception instead of Throwable
sdelamo Dec 14, 2023
76bf47e
sonar: refactor test
sdelamo Dec 14, 2023
69c09f7
AuthenticationProviderUtils and AuthenticationProviderAdapter package…
sdelamo Dec 14, 2023
dbc26ee
define generic types
sdelamo Dec 14, 2023
df280f7
fix javadoc
sdelamo Dec 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
package io.micronaut.docs.jwtclaimsoverride;

import io.micronaut.context.annotation.Requires;
import io.micronaut.security.authentication.AuthenticationProvider;
import io.micronaut.security.authentication.provider.ReactiveAuthenticationProvider;
import io.micronaut.security.authentication.AuthenticationRequest;
import io.micronaut.security.authentication.AuthenticationResponse;
import jakarta.inject.Singleton;
Expand All @@ -14,10 +14,10 @@
@Requires(property = "spec.name", value = "jwtclaimsoverride")
//tag::clazz[]
@Singleton
public class CustomAuthenticationProvider<T> implements AuthenticationProvider<T> {
public class CustomAuthenticationProvider<T> implements ReactiveAuthenticationProvider<T> {

@Override
public Publisher<AuthenticationResponse> authenticate(T httpRequest, AuthenticationRequest<?, ?> authenticationRequest) {
public Publisher<AuthenticationResponse> authenticate(T requestContext, AuthenticationRequest<?, ?> authenticationRequest) {
return Flux.create(emitter -> {
emitter.next(AuthenticationResponse.success("sherlock", Collections.singletonMap("email", "[email protected]")));
emitter.complete();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import io.micronaut.http.annotation.Produces
import io.micronaut.http.client.HttpClient
import io.micronaut.runtime.server.EmbeddedServer
import io.micronaut.security.annotation.Secured
import io.micronaut.security.authentication.AuthenticationProvider
import io.micronaut.security.authentication.provider.ReactiveAuthenticationProvider
import io.micronaut.security.authentication.UsernamePasswordCredentials
import io.micronaut.security.rules.SecurityRule
import io.micronaut.security.testutils.authprovider.MockAuthenticationProvider
Expand Down Expand Up @@ -77,7 +77,7 @@ class JwksSpec extends Specification {
RSAJwkProvider,
JwkProvider,
RSASignatureGeneratorConfiguration,
AuthenticationProvider,
ReactiveAuthenticationProvider,
]) {
gatewayEmbeddedServer.applicationContext.getBean(beanClazz)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public LdapAuthenticationProvider(LdapConfiguration configuration,
}

@Override
public Publisher<AuthenticationResponse> authenticate(T httpRequest, AuthenticationRequest<?, ?> authenticationRequest) {
public Publisher<AuthenticationResponse> authenticate(T requestContext, AuthenticationRequest<?, ?> authenticationRequest) {
Flux<AuthenticationResponse> reactiveSequence = Flux.create(emitter -> {
String username = authenticationRequest.getIdentity().toString();
String password = authenticationRequest.getSecret().toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
*/
package io.micronaut.security.oauth2.endpoint.token.request.password;

import io.micronaut.security.authentication.AuthenticationProvider;
import io.micronaut.security.authentication.AuthenticationRequest;
import io.micronaut.security.authentication.AuthenticationResponse;
import io.micronaut.security.authentication.AuthenticationProvider;
import io.micronaut.security.oauth2.configuration.OauthClientConfiguration;
import io.micronaut.security.oauth2.configuration.endpoints.SecureEndpointConfiguration;
import io.micronaut.security.oauth2.endpoint.AuthenticationMethod;
Expand Down Expand Up @@ -61,7 +61,7 @@ public OauthPasswordAuthenticationProvider(TokenEndpointClient tokenEndpointClie
}

@Override
public Publisher<AuthenticationResponse> authenticate(T httpRequest, AuthenticationRequest<?, ?> authenticationRequest) {
public Publisher<AuthenticationResponse> authenticate(T requestContext, AuthenticationRequest<?, ?> authenticationRequest) {

OauthPasswordTokenRequestContext context = new OauthPasswordTokenRequestContext(authenticationRequest, secureEndpoint, clientConfiguration);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ public OpenIdPasswordAuthenticationProvider(OauthClientConfiguration clientConfi
}

@Override
public Publisher<AuthenticationResponse> authenticate(T httpRequest, AuthenticationRequest<?, ?> authenticationRequest) {
public Publisher<AuthenticationResponse> authenticate(T requestContext, AuthenticationRequest<?, ?> authenticationRequest) {

OpenIdPasswordTokenRequestContext requestContext = new OpenIdPasswordTokenRequestContext(authenticationRequest, secureEndpoint, clientConfiguration);
OpenIdPasswordTokenRequestContext openIdPasswordTokenRequestContext = new OpenIdPasswordTokenRequestContext(authenticationRequest, secureEndpoint, clientConfiguration);

return Flux.from(
tokenEndpointClient.sendRequest(requestContext))
tokenEndpointClient.sendRequest(openIdPasswordTokenRequestContext))
.switchMap(response -> {
Optional<JWT> jwt = tokenResponseValidator.validate(clientConfiguration, openIdProviderMetadata, response, null);
if (jwt.isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import io.micronaut.context.annotation.Requires;
import io.micronaut.core.annotation.Internal;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.security.authentication.AuthenticationProvider;
import io.micronaut.security.authentication.provider.ReactiveAuthenticationProvider;
import io.micronaut.security.oauth2.client.OpenIdProviderMetadata;
import io.micronaut.security.oauth2.configuration.OauthClientConfiguration;
import io.micronaut.security.oauth2.endpoint.token.request.TokenEndpointClient;
Expand All @@ -31,7 +31,7 @@
import io.micronaut.security.oauth2.endpoint.token.response.validation.OpenIdTokenResponseValidator;

/**
* Factory creating {@link AuthenticationProvider} beans that delegate
* Factory creating {@link ReactiveAuthenticationProvider} beans that delegate
* to the password grant flow of an OAuth 2.0 or OpenID provider.
*
* @author James Kleeh
Expand Down Expand Up @@ -61,7 +61,7 @@ class PasswordGrantFactory {
*/
@EachBean(OauthClientConfiguration.class)
@Requires(condition = PasswordGrantCondition.class)
AuthenticationProvider passwordGrantProvider(
ReactiveAuthenticationProvider passwordGrantProvider(
@Parameter OauthClientConfiguration clientConfiguration,
@Parameter @Nullable OauthAuthenticationMapper authenticationMapper,
@Parameter @Nullable OpenIdAuthenticationMapper openIdAuthenticationMapper,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import io.micronaut.context.annotation.Requires
import io.micronaut.core.annotation.Nullable
import io.micronaut.json.JsonMapper
import io.micronaut.json.tree.JsonNode
import io.micronaut.security.authentication.AuthenticationProvider
import io.micronaut.security.authentication.provider.ReactiveAuthenticationProvider
import io.micronaut.security.authentication.AuthenticationRequest
import io.micronaut.security.authentication.AuthenticationResponse
import io.micronaut.security.oauth2.configuration.OauthClientConfiguration
Expand Down Expand Up @@ -64,10 +64,10 @@ class PasswordGrantConditionSpec extends Specification {
ApplicationContext ctx = ApplicationContext.run(PROPS + properties)

expect:
ctx.containsBean(AuthenticationProvider)
ctx.containsBean(ReactiveAuthenticationProvider)

when:
ctx.getBean(AuthenticationProvider)
ctx.getBean(ReactiveAuthenticationProvider)

then:
noExceptionThrown()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Produces
import io.micronaut.http.client.exceptions.HttpClientResponseException
import io.micronaut.security.annotation.Secured
import io.micronaut.security.authentication.AuthenticationProvider
import io.micronaut.security.authentication.provider.ReactiveAuthenticationProvider
import io.micronaut.security.authentication.AuthenticationRequest
import io.micronaut.security.authentication.AuthenticationResponse
import io.micronaut.security.rules.SecurityRule
Expand Down Expand Up @@ -71,10 +71,10 @@ class ContextPathSpec extends EmbeddedServerSpecification {

@Requires(property = 'spec.name', value = 'ContextPathSpec')
@Singleton
static class MockAuthenticationProvider<T> implements AuthenticationProvider<T> {
static class MockAuthenticationProvider<T> implements ReactiveAuthenticationProvider<T> {

@Override
Publisher<AuthenticationResponse> authenticate(T httpRequest, AuthenticationRequest<?, ?> authenticationRequest) {
Publisher<AuthenticationResponse> authenticate(T requestContext, AuthenticationRequest<?, ?> authenticationRequest) {
return Mono.<AuthenticationResponse>create(emitter -> {
if (authenticationRequest.identity =="user" && authenticationRequest.secret == "password") {
emitter.success(AuthenticationResponse.success("user"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
*/
package io.micronaut.security.authentication;

import io.micronaut.core.annotation.Nullable;
import org.reactivestreams.Publisher;
import io.micronaut.security.authentication.provider.ReactiveAuthenticationProvider;

/**
* Defines an authentication provider.
Expand All @@ -25,20 +24,8 @@
* @author Graeme Rocher
* @since 1.0
* @param <T> Request
* @deprecated Use {@link io.micronaut.security.authentication.provider.AuthenticationProvider} for an imperative API or {@link ReactiveAuthenticationProvider} for a reactive API instead.
*/
public interface AuthenticationProvider<T> {

/**
* Authenticates a user with the given request. If a successful authentication is
* returned, the object must be an instance of {@link Authentication}.
*
* Publishers <b>MUST emit cold observables</b>! This method will be called for
* all authenticators for each authentication request and it is assumed no work
* will be done until the publisher is subscribed to.
*
* @param httpRequest The http request
* @param authenticationRequest The credentials to authenticate
* @return A publisher that emits 0 or 1 responses
*/
Publisher<AuthenticationResponse> authenticate(@Nullable T httpRequest, AuthenticationRequest<?, ?> authenticationRequest);
@Deprecated(forRemoval = true, since = "4.5.0")
public interface AuthenticationProvider<T> extends ReactiveAuthenticationProvider<T> {
}
Loading
Loading