Uploaded image for project: 'Apache NiFi'
  1. Apache NiFi
  2. NIFI-11781

Azure AD SSO with OIDC fails in NiFi 1.21.0 and 1.22.0

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Blocker
    • Resolution: Fixed
    • 1.21.0, 1.22.0
    • 2.0.0-M1, 1.23.0
    • None
    • None
    • Docker container from https://hub.docker.com/r/apache/nifi tags v1.21, v1.22
    • Important

    Description

      I have successfully applied the instructions for NiFi 1.19, 1.20. It works perfectly for upn claim.
      After changing docker image to 1.21, 1.22 I faced an issue with accounts which do not have emails assigned in Azure AD.
      In the NiFi release notes I see 'Refactored OpenID Connect integration with support for Refresh Tokens' - https://cwiki.apache.org/confluence/display/NIFI/Release+Notes#ReleaseNotes-Version1.21.0 Isn't this a case?

      With accounts that have 'email' property in Azure AD AND nifi.security.user.oidc.claim.identifying.user=email everything works fine.

      NiFi is configured as follows:

      nifi.properties:

      # OpenId Connect SSO Properties #
      nifi.security.user.oidc.discovery.url=https://login.microsoftonline.com/{{tenantid}}/v2.0/.well-known/openid-configuration
      nifi.security.user.oidc.connect.timeout=5 secs
      nifi.security.user.oidc.read.timeout=5 secs
      nifi.security.user.oidc.client.id=<client.id>
      nifi.security.user.oidc.client.secret=<client.secret>
      nifi.security.user.oidc.preferred.jwsalgorithm=
      nifi.security.user.oidc.claim.identifying.user=upn
      nifi.security.user.oidc.additional.scopes=profile

      authorizers.xml:

          <userGroupProvider>
              <identifier>aad-user-group-provider</identifier>
              <class&amp;gt;org.apache.nifi.authorization.azure.AzureGraphUserGroupProvider</class&amp;gt;
              <property name="Refresh Delay">5 mins</property>
              <property name="Authority Endpoint">https://login.microsoftonline.com</property>
              <property name="Directory ID">{{.Values.auth.oidc.tenantId}}</property>
              <property name="Application ID">{{.Values.auth.oidc.clientId}}</property>
              <property name="Client Secret">{{.Values.auth.oidc.clientSecret}}</property>
              <property name="Group Filter Prefix">PR</property>
              <property name="Page Size">100</property>
          </userGroupProvider>

      app logs output:

       

      <h2 style="color: rgb(0, 0, 0); font-family: Times; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">HTTP ERROR 500 java.lang.IllegalArgumentException: Missing attribute 'upn' in attributes</h2>
      URI: | /nifi-api/access/oidc/callback
      -- | --
      500
      java.lang.IllegalArgumentException: Missing attribute 'upn' in attributes
      jerseySpring
      java.lang.IllegalArgumentException: Missing attribute 'upn' in attributes
      <h3 style="color: rgb(0, 0, 0); font-family: Times; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">Caused by:</h3><pre style="color: rgb(0, 0, 0); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">java.lang.IllegalArgumentException: Missing attribute 'upn' in attributes
          at org.springframework.security.oauth2.core.user.DefaultOAuth2User.&lt;init&gt;(DefaultOAuth2User.java:72)
          at org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService.loadUser(DefaultOAuth2UserService.java:116)
          at org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService.loadUser(OidcUserService.java:109)
          at org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService.loadUser(OidcUserService.java:66)
          at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.authenticate(OidcAuthorizationCodeAuthenticationProvider.java:156)
          at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182)
          at org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter.attemptAuthentication(OAuth2LoginAuthenticationFilter.java:195)
          at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:231)
          at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:221)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:361)
          at org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter.doFilterInternal(BearerTokenAuthenticationFilter.java:132)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:361)
          at org.apache.nifi.web.security.NiFiAuthenticationFilter.authenticate(NiFiAuthenticationFilter.java:94)
          at org.apache.nifi.web.security.NiFiAuthenticationFilter.doFilter(NiFiAuthenticationFilter.java:56)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:361)
          at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:118)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:361)
          at org.apache.nifi.web.security.logout.StandardLogoutFilter.doFilterInternal(StandardLogoutFilter.java:64)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:361)
          at org.apache.nifi.web.security.csrf.SkipReplicatedCsrfFilter.doFilterInternal(SkipReplicatedCsrfFilter.java:59)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:361)
          at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
          at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:361)
          at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:225)
          at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:190)
          at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)
          at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)
          at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
          at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
          at org.apache.nifi.web.filter.ExceptionFilter.doFilter(ExceptionFilter.java:46)
          at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:201)
          at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
          at org.eclipse.jetty.servlets.DoSFilter.doFilterChain(DoSFilter.java:487)
          at org.apache.nifi.web.server.filter.DataTransferExcludedDoSFilter.doFilterChain(DataTransferExcludedDoSFilter.java:51)
          at org.eclipse.jetty.servlets.DoSFilter.doFilter(DoSFilter.java:336)
          at org.eclipse.jetty.servlets.DoSFilter.doFilter(DoSFilter.java:301)
          at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
          at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
          at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
          at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
          at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
          at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
          at org.apache.nifi.web.server.log.RequestAuthenticationFilter.doFilterInternal(RequestAuthenticationFilter.java:59)
          at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
          at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
          at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
          at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:552)
          at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
          at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600)
          at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
          at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
          at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
          at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
          at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440)
          at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
          at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505)
          at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
          at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
          at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355)
          at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
          at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:146)
          at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:772)
          at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:191)
          at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:59)
          at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
          at org.eclipse.jetty.server.Server.handle(Server.java:516)
          at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487)
          at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)
          at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)
          at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
          at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
          at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
          at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:555)
          at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:410)
          at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:164)
          at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
          at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
          at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
          at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
          at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
          at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
          at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409)
          at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
          at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
          at java.base/java.lang.Thread.run(Unknown Source)</pre>
      

      Attempts to use 'preferred_username' for 
      nifi.security.user.oidc.claim.identifying.user=preferred_username resulted in the same.

      Optional claim for ID Tokens also added in Azure AD.

      So, NiFi accepts nothing but 'email' for this parameter.

      Attachments

        Issue Links

          Activity

            People

              exceptionfactory David Handermann
              evgenity Evgenity
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 20m
                  20m