[ 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)
|