Search in sources :

Example 1 with AuthenticationRequest

use of org.apache.nifi.registry.security.authentication.AuthenticationRequest in project nifi-registry by apache.

the class AccessResource method createAccessTokenUsingIdentityProviderCredentials.

/**
 * Creates a token for accessing the REST API using a custom identity provider configured using NiFi Registry extensions.
 *
 * @param httpServletRequest the servlet request
 * @return A JWT (string)
 */
@POST
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.TEXT_PLAIN)
@Path("/token/identity-provider")
@ApiOperation(value = "Creates a token for accessing the REST API via a custom identity provider.", notes = "The user credentials must be passed in a format understood by the custom identity provider, e.g., a third-party auth token in an HTTP header. " + "The exact format of the user credentials expected by the custom identity provider can be discovered by 'GET /access/token/identity-provider/usage'. " + "The token returned is formatted as a JSON Web Token (JWT). The token is base64 encoded and comprised of three parts. The header, " + "the body, and the signature. The expiration of the token is a contained within the body. The token can be used in the Authorization header " + "in the format 'Authorization: Bearer <token>'.", response = String.class)
@ApiResponses({ @ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), @ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), @ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409 + " The NiFi Registry may not be configured to support login with customized credentials."), @ApiResponse(code = 500, message = HttpStatusMessages.MESSAGE_500) })
public Response createAccessTokenUsingIdentityProviderCredentials(@Context HttpServletRequest httpServletRequest) {
    // only support access tokens when communicating over HTTPS
    if (!httpServletRequest.isSecure()) {
        throw new IllegalStateException("Access tokens are only issued over HTTPS");
    }
    // if not configured with custom identity provider, don't consider credentials
    if (identityProvider == null) {
        throw new IllegalStateException("Custom login not supported by this NiFi Registry");
    }
    AuthenticationRequest authenticationRequest = identityProvider.extractCredentials(httpServletRequest);
    if (authenticationRequest == null) {
        throw new UnauthorizedException("The client credentials are missing from the request.").withAuthenticateChallenge(identityProvider.getUsageInstructions().getAuthType());
    }
    final String token;
    try {
        token = createAccessToken(identityProvider, authenticationRequest);
    } catch (InvalidCredentialsException ice) {
        throw new UnauthorizedException("The supplied client credentials are not valid.", ice).withAuthenticateChallenge(identityProvider.getUsageInstructions().getAuthType());
    }
    // build the response
    final URI uri = URI.create(generateResourceUri("access", "token"));
    return generateCreatedResponse(uri, token).build();
}
Also used : InvalidCredentialsException(org.apache.nifi.registry.security.authentication.exception.InvalidCredentialsException) UnauthorizedException(org.apache.nifi.registry.web.exception.UnauthorizedException) AuthenticationRequest(org.apache.nifi.registry.security.authentication.AuthenticationRequest) URI(java.net.URI) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 2 with AuthenticationRequest

use of org.apache.nifi.registry.security.authentication.AuthenticationRequest in project nifi-registry by apache.

the class AccessResource method createAccessTokenUsingKerberosTicket.

@POST
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.TEXT_PLAIN)
@Path("/token/kerberos")
@ApiOperation(value = "Creates a token for accessing the REST API via Kerberos Service Tickets or SPNEGO Tokens (which includes Kerberos Service Tickets)", notes = "The token returned is formatted as a JSON Web Token (JWT). The token is base64 encoded and comprised of three parts. The header, " + "the body, and the signature. The expiration of the token is a contained within the body. The token can be used in the Authorization header " + "in the format 'Authorization: Bearer <token>'.", response = String.class)
@ApiResponses({ @ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), @ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), @ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409 + " The NiFi Registry may not be configured to support login Kerberos credentials."), @ApiResponse(code = 500, message = HttpStatusMessages.MESSAGE_500) })
public Response createAccessTokenUsingKerberosTicket(@Context HttpServletRequest httpServletRequest) {
    // only support access tokens when communicating over HTTPS
    if (!httpServletRequest.isSecure()) {
        throw new IllegalStateException("Access tokens are only issued over HTTPS");
    }
    // if not configured with custom identity provider, don't consider credentials
    if (!properties.isKerberosSpnegoSupportEnabled() || kerberosSpnegoIdentityProvider == null) {
        throw new IllegalStateException("Kerberos service ticket login not supported by this NiFi Registry");
    }
    AuthenticationRequest authenticationRequest = kerberosSpnegoIdentityProvider.extractCredentials(httpServletRequest);
    if (authenticationRequest == null) {
        throw new UnauthorizedException("The client credentials are missing from the request.").withAuthenticateChallenge(kerberosSpnegoIdentityProvider.getUsageInstructions().getAuthType());
    }
    final String token;
    try {
        token = createAccessToken(kerberosSpnegoIdentityProvider, authenticationRequest);
    } catch (final InvalidCredentialsException ice) {
        throw new UnauthorizedException("The supplied client credentials are not valid.", ice).withAuthenticateChallenge(kerberosSpnegoIdentityProvider.getUsageInstructions().getAuthType());
    }
    // build the response
    final URI uri = URI.create(generateResourceUri("access", "token"));
    return generateCreatedResponse(uri, token).build();
}
Also used : InvalidCredentialsException(org.apache.nifi.registry.security.authentication.exception.InvalidCredentialsException) UnauthorizedException(org.apache.nifi.registry.web.exception.UnauthorizedException) AuthenticationRequest(org.apache.nifi.registry.security.authentication.AuthenticationRequest) URI(java.net.URI) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Example 3 with AuthenticationRequest

use of org.apache.nifi.registry.security.authentication.AuthenticationRequest in project nifi-registry by apache.

the class X509IdentityAuthenticationProvider method buildAuthenticatedToken.

@Override
protected AuthenticationSuccessToken buildAuthenticatedToken(AuthenticationRequestToken requestToken, AuthenticationResponse response) {
    AuthenticationRequest authenticationRequest = requestToken.getAuthenticationRequest();
    String proxiedEntitiesChain = authenticationRequest.getDetails() != null ? (String) authenticationRequest.getDetails() : null;
    if (StringUtils.isBlank(proxiedEntitiesChain)) {
        return super.buildAuthenticatedToken(requestToken, response);
    }
    // build the entire proxy chain if applicable - <end-user><proxy1><proxy2>
    final List<String> proxyChain = ProxiedEntitiesUtils.tokenizeProxiedEntitiesChain(proxiedEntitiesChain);
    proxyChain.add(response.getIdentity());
    // add the chain as appropriate to each proxy
    NiFiUser proxy = null;
    for (final ListIterator<String> chainIter = proxyChain.listIterator(proxyChain.size()); chainIter.hasPrevious(); ) {
        String identity = chainIter.previous();
        // determine if the user is anonymous
        final boolean isAnonymous = StringUtils.isBlank(identity);
        if (isAnonymous) {
            identity = StandardNiFiUser.ANONYMOUS_IDENTITY;
        } else {
            identity = mapIdentity(identity);
        }
        final Set<String> groups = getUserGroups(identity);
        // Only set the client address for client making the request because we don't know the clientAddress of the proxied entities
        String clientAddress = (proxy == null) ? requestToken.getClientAddress() : null;
        proxy = createUser(identity, groups, proxy, clientAddress, isAnonymous);
        if (chainIter.hasPrevious()) {
            try {
                PROXY_AUTHORIZABLE.authorize(authorizer, RequestAction.WRITE, proxy);
            } catch (final AccessDeniedException e) {
                throw new UntrustedProxyException(String.format("Untrusted proxy [%s].", identity));
            }
        }
    }
    return new AuthenticationSuccessToken(new NiFiUserDetails(proxy));
}
Also used : AccessDeniedException(org.apache.nifi.registry.security.authorization.exception.AccessDeniedException) StandardNiFiUser(org.apache.nifi.registry.security.authorization.user.StandardNiFiUser) NiFiUser(org.apache.nifi.registry.security.authorization.user.NiFiUser) UntrustedProxyException(org.apache.nifi.registry.web.security.authentication.exception.UntrustedProxyException) AuthenticationSuccessToken(org.apache.nifi.registry.web.security.authentication.AuthenticationSuccessToken) AuthenticationRequest(org.apache.nifi.registry.security.authentication.AuthenticationRequest) NiFiUserDetails(org.apache.nifi.registry.security.authorization.user.NiFiUserDetails)

Example 4 with AuthenticationRequest

use of org.apache.nifi.registry.security.authentication.AuthenticationRequest in project nifi-registry by apache.

the class IdentityFilter method doFilter.

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    // Only require authentication from an identity provider if the NiFi registry is running securely.
    if (!servletRequest.isSecure()) {
        // Otherwise, requests will be "authenticated" by the AnonymousIdentityFilter
        filterChain.doFilter(servletRequest, servletResponse);
        return;
    }
    if (identityProvider == null) {
        logger.warn("Identity Filter configured with NULL identity provider. Credentials will not be extracted.");
        filterChain.doFilter(servletRequest, servletResponse);
        return;
    }
    if (credentialsAlreadyPresent()) {
        logger.debug("Credentials already extracted for [{}], skipping credentials extraction filter using {}", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString(), identityProvider.getClass().getSimpleName());
        filterChain.doFilter(servletRequest, servletResponse);
        return;
    }
    logger.debug("Attempting to extract user credentials using {}", identityProvider.getClass().getSimpleName());
    try {
        AuthenticationRequest authenticationRequest = identityProvider.extractCredentials((HttpServletRequest) servletRequest);
        if (authenticationRequest != null) {
            Authentication authentication = new AuthenticationRequestToken(authenticationRequest, identityProvider.getClass(), servletRequest.getRemoteAddr());
            logger.debug("Adding credentials claim to SecurityContext to be authenticated. Credentials extracted by {}: {}", identityProvider.getClass().getSimpleName(), authenticationRequest);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        // This filter's job, which is merely to search for and extract an identity claim, is done.
        // The actual authentication of the identity claim will be handled by a corresponding IdentityAuthenticationProvider
        }
    } catch (Exception e) {
        logger.debug("Exception occurred while extracting credentials:", e);
    }
    filterChain.doFilter(servletRequest, servletResponse);
}
Also used : Authentication(org.springframework.security.core.Authentication) AuthenticationRequest(org.apache.nifi.registry.security.authentication.AuthenticationRequest) ServletException(javax.servlet.ServletException) IOException(java.io.IOException)

Example 5 with AuthenticationRequest

use of org.apache.nifi.registry.security.authentication.AuthenticationRequest in project nifi-registry by apache.

the class AccessResource method createAccessTokenUsingBasicAuthCredentials.

/**
 * Creates a token for accessing the REST API.
 *
 * @param httpServletRequest the servlet request
 * @return A JWT (string)
 */
@POST
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.TEXT_PLAIN)
@Path("/token/login")
@ApiOperation(value = "Creates a token for accessing the REST API via username/password", notes = "The user credentials must be passed in standard HTTP Basic Auth format. " + "That is: 'Authorization: Basic <credentials>', where <credentials> is the base64 encoded value of '<username>:<password>'. " + "The token returned is formatted as a JSON Web Token (JWT). The token is base64 encoded and comprised of three parts. The header, " + "the body, and the signature. The expiration of the token is a contained within the body. The token can be used in the Authorization header " + "in the format 'Authorization: Bearer <token>'.", response = String.class, authorizations = { @Authorization("BasicAuth") })
@ApiResponses({ @ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), @ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), @ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409 + " The NiFi Registry may not be configured to support login with username/password."), @ApiResponse(code = 500, message = HttpStatusMessages.MESSAGE_500) })
public Response createAccessTokenUsingBasicAuthCredentials(@Context HttpServletRequest httpServletRequest) {
    // only support access tokens when communicating over HTTPS
    if (!httpServletRequest.isSecure()) {
        throw new IllegalStateException("Access tokens are only issued over HTTPS");
    }
    // if not configured with custom identity provider, or if provider doesn't support HTTP Basic Auth, don't consider credentials
    if (identityProvider == null) {
        logger.debug("An Identity Provider must be configured to use this endpoint. Please consult the administration guide.");
        throw new IllegalStateException("Username/Password login not supported by this NiFi. Contact System Administrator.");
    }
    if (!(identityProvider instanceof BasicAuthIdentityProvider)) {
        logger.debug("An Identity Provider is configured, but it does not support HTTP Basic Auth authentication. " + "The configured Identity Provider must extend {}", BasicAuthIdentityProvider.class);
        throw new IllegalStateException("Username/Password login not supported by this NiFi. Contact System Administrator.");
    }
    // generate JWT for response
    AuthenticationRequest authenticationRequest = identityProvider.extractCredentials(httpServletRequest);
    if (authenticationRequest == null) {
        throw new UnauthorizedException("The client credentials are missing from the request.").withAuthenticateChallenge(IdentityProviderUsage.AuthType.OTHER);
    }
    final String token;
    try {
        token = createAccessToken(identityProvider, authenticationRequest);
    } catch (final InvalidCredentialsException ice) {
        throw new UnauthorizedException("The supplied client credentials are not valid.", ice).withAuthenticateChallenge(IdentityProviderUsage.AuthType.OTHER);
    }
    // form the response
    final URI uri = URI.create(generateResourceUri("access", "token"));
    return generateCreatedResponse(uri, token).build();
}
Also used : InvalidCredentialsException(org.apache.nifi.registry.security.authentication.exception.InvalidCredentialsException) UnauthorizedException(org.apache.nifi.registry.web.exception.UnauthorizedException) AuthenticationRequest(org.apache.nifi.registry.security.authentication.AuthenticationRequest) URI(java.net.URI) BasicAuthIdentityProvider(org.apache.nifi.registry.security.authentication.BasicAuthIdentityProvider) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses)

Aggregations

AuthenticationRequest (org.apache.nifi.registry.security.authentication.AuthenticationRequest)8 ApiOperation (io.swagger.annotations.ApiOperation)5 ApiResponses (io.swagger.annotations.ApiResponses)5 Consumes (javax.ws.rs.Consumes)5 POST (javax.ws.rs.POST)5 Path (javax.ws.rs.Path)5 Produces (javax.ws.rs.Produces)5 InvalidCredentialsException (org.apache.nifi.registry.security.authentication.exception.InvalidCredentialsException)5 UnauthorizedException (org.apache.nifi.registry.web.exception.UnauthorizedException)5 URI (java.net.URI)4 BasicAuthIdentityProvider (org.apache.nifi.registry.security.authentication.BasicAuthIdentityProvider)2 IOException (java.io.IOException)1 Objects (java.util.Objects)1 ServletException (javax.servlet.ServletException)1 AuthenticationResponse (org.apache.nifi.registry.security.authentication.AuthenticationResponse)1 IdentityProvider (org.apache.nifi.registry.security.authentication.IdentityProvider)1 AccessDeniedException (org.apache.nifi.registry.security.authorization.exception.AccessDeniedException)1 NiFiUser (org.apache.nifi.registry.security.authorization.user.NiFiUser)1 NiFiUserDetails (org.apache.nifi.registry.security.authorization.user.NiFiUserDetails)1 StandardNiFiUser (org.apache.nifi.registry.security.authorization.user.StandardNiFiUser)1