Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 9BE7B200CFF for ; Wed, 2 Aug 2017 00:47:05 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 9A504168243; Tue, 1 Aug 2017 22:47:05 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id C104716823D for ; Wed, 2 Aug 2017 00:47:04 +0200 (CEST) Received: (qmail 51161 invoked by uid 500); 1 Aug 2017 22:47:04 -0000 Mailing-List: contact issues-help@nifi.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@nifi.apache.org Delivered-To: mailing list issues@nifi.apache.org Received: (qmail 51152 invoked by uid 99); 1 Aug 2017 22:47:03 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 01 Aug 2017 22:47:03 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 7C0701A0787 for ; Tue, 1 Aug 2017 22:47:03 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -100.002 X-Spam-Level: X-Spam-Status: No, score=-100.002 tagged_above=-999 required=6.31 tests=[RP_MATCHES_RCVD=-0.001, SPF_PASS=-0.001, USER_IN_WHITELIST=-100] autolearn=disabled Received: from mx1-lw-us.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id STrj2UT3vaZW for ; Tue, 1 Aug 2017 22:47:01 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with ESMTP id 3DA925FAC5 for ; Tue, 1 Aug 2017 22:47:01 +0000 (UTC) Received: from jira-lw-us.apache.org (unknown [207.244.88.139]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id B06B0E09A4 for ; Tue, 1 Aug 2017 22:47:00 +0000 (UTC) Received: from jira-lw-us.apache.org (localhost [127.0.0.1]) by jira-lw-us.apache.org (ASF Mail Server at jira-lw-us.apache.org) with ESMTP id 5EDB92462A for ; Tue, 1 Aug 2017 22:47:00 +0000 (UTC) Date: Tue, 1 Aug 2017 22:47:00 +0000 (UTC) From: "ASF GitHub Bot (JIRA)" To: issues@nifi.apache.org Message-ID: In-Reply-To: References: Subject: [jira] [Commented] (NIFI-4210) Add OpenId Connect support for authenticating users MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 archived-at: Tue, 01 Aug 2017 22:47:05 -0000 [ https://issues.apache.org/jira/browse/NIFI-4210?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16109934#comment-16109934 ] ASF GitHub Bot commented on NIFI-4210: -------------------------------------- Github user alopresto commented on a diff in the pull request: https://github.com/apache/nifi/pull/2047#discussion_r130748112 --- Diff: nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/AccessResource.java --- @@ -125,6 +142,160 @@ public Response getLoginConfig(@Context HttpServletRequest httpServletRequest) { return generateOkResponse(entity).build(); } + @GET + @Consumes(MediaType.WILDCARD) + @Produces(MediaType.WILDCARD) + @Path("oidc/request") + @ApiOperation( + value = "Initiates a request to authenticate through the configured OpenId Connect provider." + ) + public void oidcRequest(@Context HttpServletRequest httpServletRequest, @Context HttpServletResponse httpServletResponse) throws Exception { + // only consider user specific access over https + if (!httpServletRequest.isSecure()) { + forwardToMessagePage(httpServletRequest, httpServletResponse, "User authentication/authorization is only supported when running over HTTPS."); + return; + } + + // ensure oidc is enabled + if (!oidcService.isOidcEnabled()) { + forwardToMessagePage(httpServletRequest, httpServletResponse, "OpenId Connect is not configured."); + return; + } + + final String oidcRequestIdentifier = UUID.randomUUID().toString(); + + // generate a cookie to associate this login sequence + final Cookie cookie = new Cookie(OIDC_REQUEST_IDENTIFIER, oidcRequestIdentifier); + cookie.setPath("/"); + cookie.setHttpOnly(true); + cookie.setMaxAge(60); + cookie.setSecure(true); + httpServletResponse.addCookie(cookie); + + // get the state for this request + final State state = oidcService.createState(oidcRequestIdentifier); + + // build the authorization uri + final URI authorizationUri = UriBuilder.fromUri(oidcService.getAuthorizationEndpoint()) + .queryParam("client_id", oidcService.getClientId()) + .queryParam("response_type", "code") + .queryParam("scope", oidcService.getScope().toString()) + .queryParam("state", state.getValue()) + .queryParam("redirect_uri", getOidcCallback()) + .build(); + + // generate the response + httpServletResponse.sendRedirect(authorizationUri.toString()); + } + + @GET + @Consumes(MediaType.WILDCARD) + @Produces(MediaType.WILDCARD) + @Path("oidc/callback") + @ApiOperation( + value = "Redirect/callback URI for processing the result of the OpenId Connect login sequence." + ) + public void oidcCallback(@Context HttpServletRequest httpServletRequest, @Context HttpServletResponse httpServletResponse) throws Exception { + // only consider user specific access over https + if (!httpServletRequest.isSecure()) { + forwardToMessagePage(httpServletRequest, httpServletResponse, "User authentication/authorization is only supported when running over HTTPS."); + return; + } + + // ensure oidc is enabled + if (!oidcService.isOidcEnabled()) { + forwardToMessagePage(httpServletRequest, httpServletResponse, "OpenId Connect is not configured."); + return; + } + + final String oidcRequestIdentifier = getCookieValue(httpServletRequest.getCookies(), OIDC_REQUEST_IDENTIFIER); + if (oidcRequestIdentifier == null) { + forwardToMessagePage(httpServletRequest, httpServletResponse, "The login request identifier was not found in the request. Unable to continue."); + return; + } + + final com.nimbusds.openid.connect.sdk.AuthenticationResponse oidcResponse = AuthenticationResponseParser.parse(getRequestUri()); + if (oidcResponse.indicatesSuccess()) { + final AuthenticationSuccessResponse successfulOidcResponse = (AuthenticationSuccessResponse) oidcResponse; + + // confirm state + final State state = successfulOidcResponse.getState(); + if (!oidcService.isStateValid(oidcRequestIdentifier, state)) { + logger.error("Purposed state does not match the stored state. Unable to continue login process."); + + // remove the oidc request cookie + removeOidcRequestCookie(httpServletResponse); + + // forward to the error page + forwardToMessagePage(httpServletRequest, httpServletResponse, "Purposed state does not match the stored state. Unable to continue login process."); + return; + } + + try { + // exchange authorization code for id token + final AuthorizationCode authorizationCode = successfulOidcResponse.getAuthorizationCode(); + final AuthorizationGrant authorizationGrant = new AuthorizationCodeGrant(authorizationCode, URI.create(getOidcCallback())); + oidcService.exchangeAuthorizationCode(oidcRequestIdentifier, authorizationGrant); + } catch (final Exception e) { + logger.error("Unable to exchange authorization for ID token: " + e.getMessage(), e); + + // remove the oidc request cookie + removeOidcRequestCookie(httpServletResponse); + + // forward to the error page + forwardToMessagePage(httpServletRequest, httpServletResponse, "Unable to exchange authorization for ID token: " + e.getMessage()); + return; + } + + // redirect to the name page + httpServletResponse.sendRedirect("../../../nifi"); + } else { + // remove the oidc request cookie + removeOidcRequestCookie(httpServletResponse); + + // report the unsuccessful login + final AuthenticationErrorResponse errorOidcResponse = (AuthenticationErrorResponse) oidcResponse; + forwardToMessagePage(httpServletRequest, httpServletResponse, "Unsuccessful login attempt: " + errorOidcResponse.getErrorObject().getDescription()); + } + } + + @POST + @Consumes(MediaType.WILDCARD) + @Produces(MediaType.TEXT_PLAIN) + @Path("oidc/exchange") + @ApiOperation( + value = "Retrieves a JWT following a successful login sequence using the configured OpenId Connect provider.", + response = String.class + ) + public Response oidcExchange(@Context HttpServletRequest httpServletRequest, @Context HttpServletResponse httpServletResponse) throws Exception { + // only consider user specific access over https + if (!httpServletRequest.isSecure()) { + throw new IllegalStateException("User authentication/authorization is only supported when running over HTTPS."); + } + + // ensure oidc is enabled + if (!oidcService.isOidcEnabled()) { + throw new IllegalStateException("OpenId Connect is not configured."); + } + + final String oidcRequestIdentifier = getCookieValue(httpServletRequest.getCookies(), OIDC_REQUEST_IDENTIFIER); + if (oidcRequestIdentifier == null) { --- End diff -- Same comment as above re: validating cookie value. > Add OpenId Connect support for authenticating users > --------------------------------------------------- > > Key: NIFI-4210 > URL: https://issues.apache.org/jira/browse/NIFI-4210 > Project: Apache NiFi > Issue Type: Improvement > Components: Core Framework, Core UI > Reporter: Matt Gilman > Assignee: Matt Gilman > > Add support for authenticating users with the OpenId Connection specification. Evaluate whether a new extension point is necessary to allow for a given provider to supply custom code for instance to implement custom token validation. -- This message was sent by Atlassian JIRA (v6.4.14#64029)