Oauth 2.0 Opendistro在从KeyClope接受JWT令牌时抛出错误

Oauth 2.0 Opendistro在从KeyClope接受JWT令牌时抛出错误,oauth-2.0,jwt,openid-connect,keycloak,elasticsearch-opendistro,Oauth 2.0,Jwt,Openid Connect,Keycloak,Elasticsearch Opendistro,我正在构建一个包含三个组件的设置: 使用openid connect作为IDP的Key斗篷,以及作为客户端密码的客户端身份验证方法 带有JWT令牌配置的Opendistro安全插件 Python代码试图通过curl命令从访问令牌进行API调用 OpenDistro安全插件配置: --- --- # This is the main Open Distro Security configuration file where authentication # and authorization

我正在构建一个包含三个组件的设置:

  • 使用openid connect作为IDP的Key斗篷,以及作为客户端密码的客户端身份验证方法

  • 带有JWT令牌配置的Opendistro安全插件

  • Python代码试图通过curl命令从访问令牌进行API调用

  • OpenDistro安全插件配置:

    ---
    
    ---
    
    # This is the main Open Distro Security configuration file where authentication
    # and authorization is defined.
    #
    # You need to configure at least one authentication domain in the authc of this file.
    # An authentication domain is responsible for extracting the user credentials from
    # the request and for validating them against an authentication backend like Active Directory for example.
    #
    # If more than one authentication domain is configured the first one which succeeds wins.
    # If all authentication domains fail then the request is unauthenticated.
    # In this case an exception is thrown and/or the HTTP status is set to 401.
    #
    # After authentication authorization (authz) will be applied. There can be zero or more authorizers which collect
    # the roles from a given backend for the authenticated user.
    #
    # Both, authc and auth can be enabled/disabled separately for REST and TRANSPORT layer. Default is true for both.
    #        http_enabled: true
    #        transport_enabled: true
    #
    # For HTTP it is possible to allow anonymous authentication. If that is the case then the HTTP authenticators try to
    # find user credentials in the HTTP request. If credentials are found then the user gets regularly authenticated.
    # If none can be found the user will be authenticated as an "anonymous" user. This user has always the username "anonymous"
    # and one role named "anonymous_backendrole".
    # If you enable anonymous authentication all HTTP authenticators will not challenge.
    #
    #
    # Note: If you define more than one HTTP authenticators make sure to put non-challenging authenticators like "proxy" or "clientcert"
    # first and the challenging one last.
    # Because it's not possible to challenge a client with two different authentication methods (for example
    # Kerberos and Basic) only one can have the challenge flag set to true. You can cope with this situation
    # by using pre-authentication, e.g. sending a HTTP Basic authentication header in the request.
    #
    # Default value of the challenge flag is true.
    #
    #
    # HTTP
    #   basic (challenging)
    #   proxy (not challenging, needs xff)
    #   kerberos (challenging)
    #   clientcert (not challenging, needs https)
    #   jwt (not challenging)
    #   host (not challenging) #DEPRECATED, will be removed in a future version.
    #                          host based authentication is configurable in roles_mapping
    
    # Authc
    #   internal
    #   noop
    #   ldap
    
    # Authz
    #   ldap
    #   noop
    
    
    
    _meta:
      type: "config"
      config_version: 2
    
    config:
      dynamic:
        # Set filtered_alias_mode to 'disallow' to forbid more than 2 filtered aliases per index
        # Set filtered_alias_mode to 'warn' to allow more than 2 filtered aliases per index but warns about it (default)
        # Set filtered_alias_mode to 'nowarn' to allow more than 2 filtered aliases per index silently
        #filtered_alias_mode: warn
        #do_not_fail_on_forbidden: false
        #kibana:
        # Kibana multitenancy
        #multitenancy_enabled: true
        #server_username: kibanaserver
        #index: '.kibana'
        http:
          anonymous_auth_enabled: false
          xff:
            enabled: false
            internalProxies: '192\.168\.0\.10|192\.168\.0\.11' # regex pattern
            #internalProxies: '.*' # trust all internal proxies, regex pattern
            #remoteIpHeader:  'x-forwarded-for'
            ###### see https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html for regex help
            ###### more information about XFF https://en.wikipedia.org/wiki/X-Forwarded-For
            ###### and here https://tools.ietf.org/html/rfc7239
            ###### and https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html#Remote_IP_Valve
        authc:
          kerberos_auth_domain:
            http_enabled: false
            transport_enabled: false
            order: 6
            http_authenticator:
              type: kerberos
              challenge: true
              config:
                # If true a lot of kerberos/security related debugging output will be logged to standard out
                krb_debug: false
                # If true then the realm will be stripped from the user name
                strip_realm_from_principal: true
            authentication_backend:
              type: noop
          basic_internal_auth_domain:
            description: "Authenticate via HTTP Basic against internal users database"
            http_enabled: true
            transport_enabled: true
            order: 4
            http_authenticator:
              type: basic
              challenge: true
            authentication_backend:
              type: intern
          proxy_auth_domain:
            description: "Authenticate via proxy"
            http_enabled: false
            transport_enabled: false
            order: 3
            http_authenticator:
              type: proxy
              challenge: false
              config:
                user_header: "x-proxy-user"
                roles_header: "x-proxy-roles"
            authentication_backend:
              type: noop
          jwt_auth_domain:
            description: "Authenticate via Json Web Token"
            http_enabled: true
            transport_enabled: false
            order: 0
            http_authenticator:
              type: jwt
              challenge: false
              config:
                signing_key: "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt6GjgJTJUztz7ATm3+vYPGnnotQ5hFX57OL1UkLoqVKr+sfS6DxCl9f4/2L818TLYbtn0h9GnUOf/8XJLQpWy+B6uK3X0vVMJyzYqIaRrhUStZTXUnxOwSCzEk2sq7MT2akStA4QwtsJ9b6YbkWq4Tp0ml0kWYsqIDELnza7YJRjmDR/AFPbqiFdCANFpUtuq/heiVux9vZb881dYUmkcYtC3voH2J+KYAoCmljOtg33ioeVBLkrhzGW/7u2XJ+ELTrk7ZrXrDxpQmYaL3aojMv60BFI+WoY4xFjrTai2D1fao32I6sOcITyY6K74HCo+Fyx6cc6UiJEO5bDGrfFNQIDAQAB-----END PUBLIC KEY-----"
                jwt_header: "Authorization"
                jwt_url_parameter: null
                roles_key: roles
                subject_key: preferred_username
                openid_connect_url: "http://10.95.126.45:8080/auth/realms/demo/protocol/openid-connect/certs"
            authentication_backend:
              type: noop
          clientcert_auth_domain:
            description: "Authenticate via SSL client certificates"
            http_enabled: false
            transport_enabled: false
            order: 2
            http_authenticator:
              type: clientcert
              config:
                username_attribute: cn #optional, if omitted DN becomes username
              challenge: false
            authentication_backend:
              type: noop
          saml_auth_domain:
            http_enabled: true
            transport_enabled: false
            order: 8
            http_authenticator:
              type: saml
              challenge: true
              config:
                idp:
                  metadata_url: http://10.95.126.45:8080/auth/realms/demo/protocol/saml/descriptor
                  entity_id: http://10.95.126.45:8080/auth/realms/demo
                sp:
                  entity_id: kibana-saml
                #kibana_url: http://10.95.126.45:5601
                roles_key: Role
                exchange_key: E3B0C44298FC000000000000000000000000000000000000A495991B7852B855
            authentication_backend:
                type: noop
          ldap:
            description: "Authenticate via LDAP or Active Directory"
            http_enabled: false
            transport_enabled: false
            order: 5
            http_authenticator:
              type: basic
              challenge: false
            authentication_backend:
              # LDAP authentication backend (authenticate users against a LDAP or Active Directory)
              type: ldap
              config:
                # enable ldaps
                enable_ssl: false
                # enable start tls, enable_ssl should be false
                enable_start_tls: false
                # send client certificate
                enable_ssl_client_auth: false
                # verify ldap hostname
                verify_hostnames: true
                hosts:
                - localhost:8389
                bind_dn: null
                password: null
                userbase: 'ou=people,dc=example,dc=com'
                # Filter to search for users (currently in the whole subtree beneath userbase)
                # {0} is substituted with the username
                usersearch: '(sAMAccountName={0})'
                # Use this attribute from the user as username (if not set then DN is used)
                username_attribute: null
        authz:
          roles_from_myldap:
            description: "Authorize via LDAP or Active Directory"
            http_enabled: false
            transport_enabled: false
            authorization_backend:
              # LDAP authorization backend (gather roles from a LDAP or Active Directory, you have to configure the above LDAP authentication backend settings too)
              type: ldap
              config:
                # enable ldaps
                enable_ssl: false
                # enable start tls, enable_ssl should be false
                enable_start_tls: false
                # send client certificate
                enable_ssl_client_auth: false
                # verify ldap hostname
                verify_hostnames: true
                hosts:
                - localhost:8389
                bind_dn: null
                password: null
                rolebase: 'ou=groups,dc=example,dc=com'
                # Filter to search for roles (currently in the whole subtree beneath rolebase)
                # {0} is substituted with the DN of the user
                # {1} is substituted with the username
                # {2} is substituted with an attribute value from user's directory entry, of the authenticated user. Use userroleattribute to specify the name of the attribute
                rolesearch: '(member={0})'
                # Specify the name of the attribute which value should be substituted with {2} above
                userroleattribute: null
                # Roles as an attribute of the user entry
                userrolename: disabled
                #userrolename: memberOf
                # The attribute in a role entry containing the name of that role, Default is "name".
                # Can also be "dn" to use the full DN as rolename.
                rolename: cn
                # Resolve nested roles transitive (roles which are members of other roles and so on ...)
                resolve_nested_roles: true
                userbase: 'ou=people,dc=example,dc=com'
                # Filter to search for users (currently in the whole subtree beneath userbase)
                # {0} is substituted with the username
                usersearch: '(uid={0})'
                # Skip users matching a user name, a wildcard or a regex pattern
                #skip_users:
                #  - 'cn=Michael Jackson,ou*people,o=TEST'
                #  - '/\S*/'
          roles_from_another_ldap:
            description: "Authorize via another Active Directory"
            http_enabled: false
            transport_enabled: false
            authorization_backend:
              type: ldap
              #config goes here ...
      #    auth_failure_listeners:
      #      ip_rate_limiting:
      #        type: ip
      #        allowed_tries: 10
      #        time_window_seconds: 3600
      #        block_expiry_seconds: 600
      #        max_blocked_clients: 100000
      #        max_tracked_clients: 100000
      #      internal_authentication_backend_limiting:
      #        type: username
      #        authentication_backend: intern
      #        allowed_tries: 10
      #        time_window_seconds: 3600
      #        block_expiry_seconds: 600
      #        max_blocked_clients: 100000
      #        max_tracked_clients: 100000
    
    
    
    密钥斗篷配置:

    keydape OIDC JSON供参考:

    {
      "realm": "demo",
      "auth-server-url": "http://10.95.126.45:8080/auth/",
      "ssl-required": "none",
      "resource": "elastic-2",
      "verify-token-audience": true,
      "credentials": {
        "secret": "9e30fff3-ab4b-4b5d-89c9-0d94cf807483"
      },
      "confidential-port": 0,
      "policy-enforcer": {}
    }
    
    我查询的申请如下:

    curl http://10.95.126.45:8080/auth/realms/demo/protocol/openid-connect/token \
    -H 'Cache-Control: nocache' \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    -H 'Postman-Token: c43306f5-f2b9-46c9-b0fb-efd63314df4c' \
    -H 'cache-control: no-cache' \
    -d 'grant_type=client_credentials&client_id=elastic-2&client_secret=9e30fff3-ab4b-4b5d-89c9-0d94cf807483'
    
    [2020-03-10T11:59:06,295][INFO ][c.a.d.a.h.j.AbstractHTTPJwtAuthenticator] [localhost.localdomain] Extracting JWT token from eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJGLUpqN0VRWjU2anJoNDFrQjBsdzBoYmpreUQwNEpNVEtENDkxa0RaLTlVIn0.eyJqdGkiOiJkNzNiNWI4Ni1lNjgwLTQ0ZDMtYTgyNC00Mjk3NjVhZTM1YzkiLCJleHAiOjE1ODM4NTYwNTIsIm5iZiI6MCwiaWF0IjoxNTgzODU1NzUyLCJpc3MiOiJodHRwOi8vMTAuOTUuMTI2LjQ1OjgwODAvYXV0aC9yZWFsbXMvZGVtbyIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiJlOWI4NGJkZC1lZDgyLTQ3YWYtOTg2OC1lYzc5NDE3Y2NkOWEiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJlbGFzdGljLTIiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiI3MDcyZGRhZi1iMWVjLTQxYTUtODAwZi1lNzNlNTExMmNkMjEiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJlbGFzdGljLTIiOnsicm9sZXMiOlsidW1hX3Byb3RlY3Rpb24iXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiY2xpZW50SG9zdCI6IjEwLjk1LjEyNi40NSIsImNsaWVudElkIjoiZWxhc3RpYy0yIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic2VydmljZS1hY2NvdW50LWVsYXN0aWMtMiIsImNsaWVudEFkZHJlc3MiOiIxMC45NS4xMjYuNDUifQ.AI7_jkNAK_LD5jsgOn-wn4xdk4ZKXqAo1G7m0MjaIjco37dfxGEL-cKhDnZYvsRiULmXtsBXjBBZchOpsoyWbAczH-cNxeQ9bPwbi8saV-9sHLccTpHdZZAY_vG3JyrCaHhno4F9VnU-smks4E-fe8H-Wm1v7yfX6WiCb3txUOwE5z4VTjgNyCOsEpAVQZ2luMiwXK6a450F3DCmzg3gwfseAIPOJxfQBdGje20wK8eRMBSapEHOY75JTFM9ADjN6bOEFHhiWFeaAz0aii20tgNUcfJHCGnDPjrPdUkjy0vqYTSW1SDyhltFgoYJMF9-XWKBM3mL4ctEZw9VmKdBwA failed
    com.amazon.dlic.auth.http.jwt.keybyoidc.BadCredentialsException: Algorithm of JWT does not match algorithm of JWK (HS512 != RS256)
            at com.amazon.dlic.auth.http.jwt.keybyoidc.JwtVerifier.validateSignatureAlgorithm(JwtVerifier.java:98) ~[opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.dlic.auth.http.jwt.keybyoidc.JwtVerifier.getInitializedSignatureVerifier(JwtVerifier.java:106) ~[opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.dlic.auth.http.jwt.keybyoidc.JwtVerifier.getVerifiedJwtToken(JwtVerifier.java:66) ~[opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.dlic.auth.http.jwt.AbstractHTTPJwtAuthenticator.extractCredentials0(AbstractHTTPJwtAuthenticator.java:103) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.dlic.auth.http.jwt.AbstractHTTPJwtAuthenticator.access$000(AbstractHTTPJwtAuthenticator.java:45) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.dlic.auth.http.jwt.AbstractHTTPJwtAuthenticator$1.run(AbstractHTTPJwtAuthenticator.java:85) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.dlic.auth.http.jwt.AbstractHTTPJwtAuthenticator$1.run(AbstractHTTPJwtAuthenticator.java:82) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at java.security.AccessController.doPrivileged(AccessController.java:312) [?:?]
            at com.amazon.dlic.auth.http.jwt.AbstractHTTPJwtAuthenticator.extractCredentials(AbstractHTTPJwtAuthenticator.java:82) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.dlic.auth.http.saml.HTTPSamlAuthenticator.extractCredentials(HTTPSamlAuthenticator.java:140) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.opendistroforelasticsearch.security.auth.BackendRegistry.authenticate(BackendRegistry.java:412) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.opendistroforelasticsearch.security.filter.OpenDistroSecurityRestFilter.checkAndAuthenticateRequest(OpenDistroSecurityRestFilter.java:146) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.opendistroforelasticsearch.security.filter.OpenDistroSecurityRestFilter.access$000(OpenDistroSecurityRestFilter.java:63) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.opendistroforelasticsearch.security.filter.OpenDistroSecurityRestFilter$1.handleRequest(OpenDistroSecurityRestFilter.java:93) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at org.elasticsearch.rest.RestController.dispatchRequest(RestController.java:222) [elasticsearch-7.4.2.jar:7.4.2]
            at org.elasticsearch.rest.RestController.tryAllHandlers(RestController.java:295) [elasticsearch-7.4.2.jar:7.4.2]
            at org.elasticsearch.rest.RestController.dispatchRequest(RestController.java:166) [elasticsearch-7.4.2.jar:7.4.2]
            at com.amazon.opendistroforelasticsearch.security.ssl.http.netty.ValidatingDispatcher.dispatchRequest(ValidatingDispatcher.java:63) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at org.elasticsearch.http.AbstractHttpServerTransport.dispatchRequest(AbstractHttpServerTransport.java:322) [elasticsearch-7.4.2.jar:7.4.2]
            at org.elasticsearch.http.AbstractHttpServerTransport.handleIncomingRequest(AbstractHttpServerTransport.java:372) [elasticsearch-7.4.2.jar:7.4.2]
            at org.elasticsearch.http.AbstractHttpServerTransport.incomingRequest(AbstractHttpServerTransport.java:301) [elasticsearch-7.4.2.jar:7.4.2]
            at org.elasticsearch.http.netty4.Netty4HttpRequestHandler.channelRead0(Netty4HttpRequestHandler.java:69) [transport-netty4-client-7.4.2.jar:7.4.2]
            at org.elasticsearch.http.netty4.Netty4HttpRequestHandler.channelRead0(Netty4HttpRequestHandler.java:31) [transport-netty4-client-7.4.2.jar:7.4.2]
            at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at org.elasticsearch.http.netty4.Netty4HttpPipeliningHandler.channelRead(Netty4HttpPipeliningHandler.java:58) [transport-netty4-client-7.4.2.jar:7.4.2]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102) [netty-codec-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102) [netty-codec-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:328) [netty-codec-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:302) [netty-codec-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:287) [netty-handler-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1475) [netty-handler-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1224) [netty-handler-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1271) [netty-handler-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:505) [netty-codec-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:444) [netty-codec-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:283) [netty-codec-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1421) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:930) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:697) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:597) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:551) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:511) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:918) [netty-common-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-common-4.1.38.Final.jar:4.1.38.Final]
            at java.lang.Thread.run(Thread.java:830) [?:?]
    
    
    我可以从此命令获取访问令牌。使用jwt.io,通过将公钥放入KeyClope中领域的keys部分来验证签名

    然后,我使用python请求库查询弹性搜索

    import requests
    access_token="eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJGLUpqN0VRWjU2anJoNDFrQjBsdzBoYmpreUQwNEpNVEtENDkxa0RaLTlVIn0.eyJqdGkiOiJkNzNiNWI4Ni1lNjgwLTQ0ZDMtYTgyNC00Mjk3NjVhZTM1YzkiLCJleHAiOjE1ODM4NTYwNTIsIm5iZiI6MCwiaWF0IjoxNTgzODU1NzUyLCJpc3MiOiJodHRwOi8vMTAuOTUuMTI2LjQ1OjgwODAvYXV0aC9yZWFsbXMvZGVtbyIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiJlOWI4NGJkZC1lZDgyLTQ3YWYtOTg2OC1lYzc5NDE3Y2NkOWEiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJlbGFzdGljLTIiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiI3MDcyZGRhZi1iMWVjLTQxYTUtODAwZi1lNzNlNTExMmNkMjEiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJlbGFzdGljLTIiOnsicm9sZXMiOlsidW1hX3Byb3RlY3Rpb24iXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiY2xpZW50SG9zdCI6IjEwLjk1LjEyNi40NSIsImNsaWVudElkIjoiZWxhc3RpYy0yIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic2VydmljZS1hY2NvdW50LWVsYXN0aWMtMiIsImNsaWVudEFkZHJlc3MiOiIxMC45NS4xMjYuNDUifQ.AI7_jkNAK_LD5jsgOn-wn4xdk4ZKXqAo1G7m0MjaIjco37dfxGEL-cKhDnZYvsRiULmXtsBXjBBZchOpsoyWbAczH-cNxeQ9bPwbi8saV-9sHLccTpHdZZAY_vG3JyrCaHhno4F9VnU-smks4E-fe8H-Wm1v7yfX6WiCb3txUOwE5z4VTjgNyCOsEpAVQZ2luMiwXK6a450F3DCmzg3gwfseAIPOJxfQBdGje20wK8eRMBSapEHOY75JTFM9ADjN6bOEFHhiWFeaAz0aii20tgNUcfJHCGnDPjrPdUkjy0vqYTSW1SDyhltFgoYJMF9-XWKBM3mL4ctEZw9VmKdBwA"
    headers = {'Authorization': 'Bearer %s' % (access_token)}
                # YOLO
    response = requests.get('https://localhost:9200/demo_index*/_search', headers=headers, verify=False)
    print(response.text)
    
    注: 上面的访问令牌是有效的,您可以使用jwt opendistro的签名密钥和该令牌进行检查,以查看已验证的签名

    然而,当运行上面的python脚本时,我得到一个错误

    弹性搜索的错误如下:

    curl http://10.95.126.45:8080/auth/realms/demo/protocol/openid-connect/token \
    -H 'Cache-Control: nocache' \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    -H 'Postman-Token: c43306f5-f2b9-46c9-b0fb-efd63314df4c' \
    -H 'cache-control: no-cache' \
    -d 'grant_type=client_credentials&client_id=elastic-2&client_secret=9e30fff3-ab4b-4b5d-89c9-0d94cf807483'
    
    [2020-03-10T11:59:06,295][INFO ][c.a.d.a.h.j.AbstractHTTPJwtAuthenticator] [localhost.localdomain] Extracting JWT token from eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJGLUpqN0VRWjU2anJoNDFrQjBsdzBoYmpreUQwNEpNVEtENDkxa0RaLTlVIn0.eyJqdGkiOiJkNzNiNWI4Ni1lNjgwLTQ0ZDMtYTgyNC00Mjk3NjVhZTM1YzkiLCJleHAiOjE1ODM4NTYwNTIsIm5iZiI6MCwiaWF0IjoxNTgzODU1NzUyLCJpc3MiOiJodHRwOi8vMTAuOTUuMTI2LjQ1OjgwODAvYXV0aC9yZWFsbXMvZGVtbyIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiJlOWI4NGJkZC1lZDgyLTQ3YWYtOTg2OC1lYzc5NDE3Y2NkOWEiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJlbGFzdGljLTIiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiI3MDcyZGRhZi1iMWVjLTQxYTUtODAwZi1lNzNlNTExMmNkMjEiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIioiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJlbGFzdGljLTIiOnsicm9sZXMiOlsidW1hX3Byb3RlY3Rpb24iXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiY2xpZW50SG9zdCI6IjEwLjk1LjEyNi40NSIsImNsaWVudElkIjoiZWxhc3RpYy0yIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic2VydmljZS1hY2NvdW50LWVsYXN0aWMtMiIsImNsaWVudEFkZHJlc3MiOiIxMC45NS4xMjYuNDUifQ.AI7_jkNAK_LD5jsgOn-wn4xdk4ZKXqAo1G7m0MjaIjco37dfxGEL-cKhDnZYvsRiULmXtsBXjBBZchOpsoyWbAczH-cNxeQ9bPwbi8saV-9sHLccTpHdZZAY_vG3JyrCaHhno4F9VnU-smks4E-fe8H-Wm1v7yfX6WiCb3txUOwE5z4VTjgNyCOsEpAVQZ2luMiwXK6a450F3DCmzg3gwfseAIPOJxfQBdGje20wK8eRMBSapEHOY75JTFM9ADjN6bOEFHhiWFeaAz0aii20tgNUcfJHCGnDPjrPdUkjy0vqYTSW1SDyhltFgoYJMF9-XWKBM3mL4ctEZw9VmKdBwA failed
    com.amazon.dlic.auth.http.jwt.keybyoidc.BadCredentialsException: Algorithm of JWT does not match algorithm of JWK (HS512 != RS256)
            at com.amazon.dlic.auth.http.jwt.keybyoidc.JwtVerifier.validateSignatureAlgorithm(JwtVerifier.java:98) ~[opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.dlic.auth.http.jwt.keybyoidc.JwtVerifier.getInitializedSignatureVerifier(JwtVerifier.java:106) ~[opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.dlic.auth.http.jwt.keybyoidc.JwtVerifier.getVerifiedJwtToken(JwtVerifier.java:66) ~[opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.dlic.auth.http.jwt.AbstractHTTPJwtAuthenticator.extractCredentials0(AbstractHTTPJwtAuthenticator.java:103) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.dlic.auth.http.jwt.AbstractHTTPJwtAuthenticator.access$000(AbstractHTTPJwtAuthenticator.java:45) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.dlic.auth.http.jwt.AbstractHTTPJwtAuthenticator$1.run(AbstractHTTPJwtAuthenticator.java:85) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.dlic.auth.http.jwt.AbstractHTTPJwtAuthenticator$1.run(AbstractHTTPJwtAuthenticator.java:82) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at java.security.AccessController.doPrivileged(AccessController.java:312) [?:?]
            at com.amazon.dlic.auth.http.jwt.AbstractHTTPJwtAuthenticator.extractCredentials(AbstractHTTPJwtAuthenticator.java:82) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.dlic.auth.http.saml.HTTPSamlAuthenticator.extractCredentials(HTTPSamlAuthenticator.java:140) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.opendistroforelasticsearch.security.auth.BackendRegistry.authenticate(BackendRegistry.java:412) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.opendistroforelasticsearch.security.filter.OpenDistroSecurityRestFilter.checkAndAuthenticateRequest(OpenDistroSecurityRestFilter.java:146) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.opendistroforelasticsearch.security.filter.OpenDistroSecurityRestFilter.access$000(OpenDistroSecurityRestFilter.java:63) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at com.amazon.opendistroforelasticsearch.security.filter.OpenDistroSecurityRestFilter$1.handleRequest(OpenDistroSecurityRestFilter.java:93) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at org.elasticsearch.rest.RestController.dispatchRequest(RestController.java:222) [elasticsearch-7.4.2.jar:7.4.2]
            at org.elasticsearch.rest.RestController.tryAllHandlers(RestController.java:295) [elasticsearch-7.4.2.jar:7.4.2]
            at org.elasticsearch.rest.RestController.dispatchRequest(RestController.java:166) [elasticsearch-7.4.2.jar:7.4.2]
            at com.amazon.opendistroforelasticsearch.security.ssl.http.netty.ValidatingDispatcher.dispatchRequest(ValidatingDispatcher.java:63) [opendistro_security-1.4.0.0.jar:1.4.0.0]
            at org.elasticsearch.http.AbstractHttpServerTransport.dispatchRequest(AbstractHttpServerTransport.java:322) [elasticsearch-7.4.2.jar:7.4.2]
            at org.elasticsearch.http.AbstractHttpServerTransport.handleIncomingRequest(AbstractHttpServerTransport.java:372) [elasticsearch-7.4.2.jar:7.4.2]
            at org.elasticsearch.http.AbstractHttpServerTransport.incomingRequest(AbstractHttpServerTransport.java:301) [elasticsearch-7.4.2.jar:7.4.2]
            at org.elasticsearch.http.netty4.Netty4HttpRequestHandler.channelRead0(Netty4HttpRequestHandler.java:69) [transport-netty4-client-7.4.2.jar:7.4.2]
            at org.elasticsearch.http.netty4.Netty4HttpRequestHandler.channelRead0(Netty4HttpRequestHandler.java:31) [transport-netty4-client-7.4.2.jar:7.4.2]
            at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at org.elasticsearch.http.netty4.Netty4HttpPipeliningHandler.channelRead(Netty4HttpPipeliningHandler.java:58) [transport-netty4-client-7.4.2.jar:7.4.2]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102) [netty-codec-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102) [netty-codec-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:328) [netty-codec-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:302) [netty-codec-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:287) [netty-handler-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1475) [netty-handler-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1224) [netty-handler-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1271) [netty-handler-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:505) [netty-codec-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:444) [netty-codec-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:283) [netty-codec-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1421) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:930) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:697) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:597) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:551) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:511) [netty-transport-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:918) [netty-common-4.1.38.Final.jar:4.1.38.Final]
            at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-common-4.1.38.Final.jar:4.1.38.Final]
            at java.lang.Thread.run(Thread.java:830) [?:?]