Search in sources :

Example 1 with AuthenticationResponse

use of io.micronaut.security.authentication.AuthenticationResponse in project micronaut-security by micronaut-projects.

the class LdapAuthenticationProvider method authenticate.

@Override
public Publisher<AuthenticationResponse> authenticate(HttpRequest<?> httpRequest, AuthenticationRequest<?, ?> authenticationRequest) {
    Flux<AuthenticationResponse> reactiveSequence = Flux.create(emitter -> {
        String username = authenticationRequest.getIdentity().toString();
        String password = authenticationRequest.getSecret().toString();
        if (LOG.isDebugEnabled()) {
            LOG.debug("Starting authentication with configuration [{}]", configuration.getName());
            LOG.debug("Attempting to initialize manager context");
        }
        DirContext managerContext;
        try {
            managerContext = contextBuilder.build(configuration.getManagerSettings());
            debug(LOG, "Manager context initialized successfully");
        } catch (NamingException e) {
            debug(LOG, "Failed to create manager context. Returning unknown authentication failure. Encountered {}", e.getMessage());
            emitter.error(AuthenticationResponse.exception(AuthenticationFailureReason.UNKNOWN));
            return;
        }
        debug(LOG, "Attempting to authenticate with user [{}]", username);
        try {
            Optional<LdapSearchResult> optionalResult = ldapSearchService.searchFirst(managerContext, configuration.getSearch().getSettings(new Object[] { username }));
            if (optionalResult.isPresent()) {
                LdapSearchResult result = optionalResult.get();
                debug(LOG, "User found in context [{}]. Attempting to bind.", result.getDn());
                DirContext userContext = null;
                try {
                    String dn = result.getDn();
                    userContext = contextBuilder.build(configuration.getSettings(result.getDn(), password));
                    if (result.getAttributes() == null) {
                        result.setAttributes(userContext.getAttributes(dn));
                    }
                } finally {
                    contextBuilder.close(userContext);
                }
                debug(LOG, "Successfully bound user [{}]. Attempting to retrieving groups.", result.getDn());
                Set<String> groups = Collections.emptySet();
                LdapConfiguration.GroupConfiguration groupSettings = configuration.getGroups();
                if (groupSettings.isEnabled()) {
                    groups = ldapGroupProcessor.process(groupSettings.getAttribute(), result, () -> {
                        Object[] params = new Object[] { groupSettings.getFilterAttribute().map(attr -> result.getAttributes().getValue(attr)).orElse(result.getDn()) };
                        return ldapSearchService.search(managerContext, groupSettings.getSearchSettings(params));
                    });
                    debug(LOG, "Group search returned [{}] for user [{}]", groups, username);
                } else {
                    debug(LOG, "Group search is disabled for configuration [{}]", configuration.getName());
                }
                if (LOG.isTraceEnabled()) {
                    LOG.trace("Attempting to map [{}] with groups [{}] to an authentication response.", username, groups);
                }
                AuthenticationResponse response = contextAuthenticationMapper.map(result.getAttributes(), username, groups);
                if (response.isAuthenticated()) {
                    emitter.next(response);
                    emitter.complete();
                } else {
                    emitter.error(new AuthenticationException(response));
                }
                debug(LOG, "Response successfully created for [{}]. Response is authenticated: [{}]", username, response.isAuthenticated());
            } else {
                debug(LOG, "User not found [{}]", username);
                emitter.error(AuthenticationResponse.exception(AuthenticationFailureReason.USER_NOT_FOUND));
            }
        } catch (NamingException e) {
            debug(LOG, "Failed to authenticate with user [{}].  {}", username, e);
            if (e instanceof javax.naming.AuthenticationException) {
                emitter.error(AuthenticationResponse.exception(AuthenticationFailureReason.CREDENTIALS_DO_NOT_MATCH));
            } else {
                emitter.error(e);
            }
        } finally {
            contextBuilder.close(managerContext);
        }
    }, FluxSink.OverflowStrategy.ERROR);
    reactiveSequence = reactiveSequence.subscribeOn(scheduler);
    return reactiveSequence;
}
Also used : LdapSearchResult(io.micronaut.security.ldap.context.LdapSearchResult) AuthenticationException(io.micronaut.security.authentication.AuthenticationException) LdapConfiguration(io.micronaut.security.ldap.configuration.LdapConfiguration) DirContext(javax.naming.directory.DirContext) AuthenticationResponse(io.micronaut.security.authentication.AuthenticationResponse) NamingException(javax.naming.NamingException)

Example 2 with AuthenticationResponse

use of io.micronaut.security.authentication.AuthenticationResponse in project micronaut-graphql by micronaut-projects.

the class LoginDataFetcher method get.

@Override
public LoginPayload get(DataFetchingEnvironment environment) throws Exception {
    GraphQLContext graphQLContext = environment.getContext();
    if (LOGIN_RATE_LIMIT_REMAINING <= 0) {
        addRateLimitHeaders(graphQLContext);
        resetRateLimit();
        return LoginPayload.ofError("Rate Limit Exceeded");
    }
    HttpRequest httpRequest = graphQLContext.get("httpRequest");
    MutableHttpResponse<String> httpResponse = graphQLContext.get("httpResponse");
    String username = environment.getArgument("username");
    String password = environment.getArgument("password");
    UsernamePasswordCredentials usernamePasswordCredentials = new UsernamePasswordCredentials(username, password);
    LOGIN_RATE_LIMIT_REMAINING--;
    Flux<AuthenticationResponse> authenticationResponseFlowable = Flux.from(authenticator.authenticate(httpRequest, usernamePasswordCredentials));
    return authenticationResponseFlowable.map(authenticationResponse -> {
        addRateLimitHeaders(graphQLContext);
        if (authenticationResponse.isAuthenticated()) {
            eventPublisher.publishEvent(new LoginSuccessfulEvent(authenticationResponse));
            Optional<Cookie> jwtCookie = accessTokenCookie(Authentication.build(username), httpRequest);
            jwtCookie.ifPresent(httpResponse::cookie);
            User user = userRepository.findByUsername(username).orElse(null);
            return LoginPayload.ofUser(user);
        } else {
            eventPublisher.publishEvent(new LoginFailedEvent(authenticationResponse));
            return LoginPayload.ofError(authenticationResponse.getMessage().orElse(null));
        }
    }).blockFirst();
}
Also used : HttpRequest(io.micronaut.http.HttpRequest) DataFetchingEnvironment(graphql.schema.DataFetchingEnvironment) UsernamePasswordCredentials(io.micronaut.security.authentication.UsernamePasswordCredentials) AccessRefreshToken(io.micronaut.security.token.jwt.render.AccessRefreshToken) Cookie(io.micronaut.http.cookie.Cookie) User(example.domain.User) AccessTokenConfiguration(io.micronaut.security.token.jwt.generator.AccessTokenConfiguration) ApplicationEventPublisher(io.micronaut.context.event.ApplicationEventPublisher) MutableHttpResponse(io.micronaut.http.MutableHttpResponse) Authentication(io.micronaut.security.authentication.Authentication) Singleton(jakarta.inject.Singleton) Random(java.util.Random) CookieConfiguration(io.micronaut.http.cookie.CookieConfiguration) AccessRefreshTokenGenerator(io.micronaut.security.token.jwt.generator.AccessRefreshTokenGenerator) UserRepository(example.repository.UserRepository) Authenticator(io.micronaut.security.authentication.Authenticator) Flux(reactor.core.publisher.Flux) LoginSuccessfulEvent(io.micronaut.security.event.LoginSuccessfulEvent) GraphQLContext(graphql.GraphQLContext) DataFetcher(graphql.schema.DataFetcher) TemporalAmount(java.time.temporal.TemporalAmount) Optional(java.util.Optional) HttpRequest(io.micronaut.http.HttpRequest) LoginFailedEvent(io.micronaut.security.event.LoginFailedEvent) AuthenticationResponse(io.micronaut.security.authentication.AuthenticationResponse) User(example.domain.User) Optional(java.util.Optional) GraphQLContext(graphql.GraphQLContext) LoginSuccessfulEvent(io.micronaut.security.event.LoginSuccessfulEvent) AuthenticationResponse(io.micronaut.security.authentication.AuthenticationResponse) LoginFailedEvent(io.micronaut.security.event.LoginFailedEvent) UsernamePasswordCredentials(io.micronaut.security.authentication.UsernamePasswordCredentials)

Example 3 with AuthenticationResponse

use of io.micronaut.security.authentication.AuthenticationResponse in project micronaut-security by micronaut-projects.

the class DefaultOauthAuthorizationResponseHandler method handle.

@Override
public Publisher<AuthenticationResponse> handle(AuthorizationResponse authorizationResponse, OauthClientConfiguration clientConfiguration, OauthAuthenticationMapper authenticationMapper, SecureEndpoint tokenEndpoint) {
    State state;
    if (stateValidator != null) {
        if (LOG.isTraceEnabled()) {
            LOG.trace("Validating state found in the authorization response from provider [{}]", clientConfiguration.getName());
        }
        state = authorizationResponse.getState();
        try {
            stateValidator.validate(authorizationResponse.getCallbackRequest(), state);
        } catch (InvalidStateException e) {
            return Flux.just(new AuthenticationFailed("State validation failed: " + e.getMessage()));
        }
    } else {
        state = null;
        if (LOG.isTraceEnabled()) {
            LOG.trace("Skipping state validation, no state validator found");
        }
    }
    OauthCodeTokenRequestContext context = new OauthCodeTokenRequestContext(authorizationResponse, tokenEndpoint, clientConfiguration);
    return Flux.from(tokenEndpointClient.sendRequest(context)).switchMap(response -> {
        if (LOG.isTraceEnabled()) {
            LOG.trace("Token endpoint returned a success response. Creating a user details");
        }
        return Flux.from(authenticationMapper.createAuthenticationResponse(response, state)).map(AuthenticationResponse.class::cast);
    });
}
Also used : State(io.micronaut.security.oauth2.endpoint.authorization.state.State) AuthenticationFailed(io.micronaut.security.authentication.AuthenticationFailed) InvalidStateException(io.micronaut.security.oauth2.endpoint.authorization.state.InvalidStateException) OauthCodeTokenRequestContext(io.micronaut.security.oauth2.endpoint.token.request.context.OauthCodeTokenRequestContext) AuthenticationResponse(io.micronaut.security.authentication.AuthenticationResponse)

Aggregations

AuthenticationResponse (io.micronaut.security.authentication.AuthenticationResponse)3 User (example.domain.User)1 UserRepository (example.repository.UserRepository)1 GraphQLContext (graphql.GraphQLContext)1 DataFetcher (graphql.schema.DataFetcher)1 DataFetchingEnvironment (graphql.schema.DataFetchingEnvironment)1 ApplicationEventPublisher (io.micronaut.context.event.ApplicationEventPublisher)1 HttpRequest (io.micronaut.http.HttpRequest)1 MutableHttpResponse (io.micronaut.http.MutableHttpResponse)1 Cookie (io.micronaut.http.cookie.Cookie)1 CookieConfiguration (io.micronaut.http.cookie.CookieConfiguration)1 Authentication (io.micronaut.security.authentication.Authentication)1 AuthenticationException (io.micronaut.security.authentication.AuthenticationException)1 AuthenticationFailed (io.micronaut.security.authentication.AuthenticationFailed)1 Authenticator (io.micronaut.security.authentication.Authenticator)1 UsernamePasswordCredentials (io.micronaut.security.authentication.UsernamePasswordCredentials)1 LoginFailedEvent (io.micronaut.security.event.LoginFailedEvent)1 LoginSuccessfulEvent (io.micronaut.security.event.LoginSuccessfulEvent)1 LdapConfiguration (io.micronaut.security.ldap.configuration.LdapConfiguration)1 LdapSearchResult (io.micronaut.security.ldap.context.LdapSearchResult)1