logstash-filter-jwt-decoder 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 86e9b95e13fe378117fbcfabf261b6dc40645f67fae4fafa3488f3ae6438d641
4
+ data.tar.gz: 78d5473c390c19d062c46c4331eb3aeb56344a49c6af7ffa895076804eda20a7
5
+ SHA512:
6
+ metadata.gz: f8d11bd6c26da92df1c03f7e3214f75b8f29b37c04dda85711e6a29bd3445a57f16efd8323c0707c90c01545641dde3cb35a7b944f1b9d1e322a954923de9f36
7
+ data.tar.gz: 3151853dfb5ccfb669d96a6dc14d03c119ddb1c872decb51c5066303503b75964596e4312b886172cd3953bd44c6dd90d5cd2d037d8bd86a24976daab532e5c7
@@ -0,0 +1,7 @@
1
+ ## 3.0.2
2
+ - Docs: Add documentation template
3
+ ## 2.0.0
4
+ - Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
5
+ instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
6
+ - Dependency on logstash-core update to 2.0
7
+
@@ -0,0 +1,11 @@
1
+ The following is a list of people who have contributed ideas, code, bug
2
+ reports, or in general have helped logstash along its way.
3
+
4
+ Contributors:
5
+ * Aaron Mildenstein (untergeek)
6
+ * Pier-Hugues Pellerin (ph)
7
+
8
+ Note: If you've sent us patches, bug reports, or otherwise contributed to
9
+ Logstash, and you aren't on the list above and want to be, please let us know
10
+ and we'll make sure you're here. Contributions from folks like you are what make
11
+ open source awesome.
@@ -0,0 +1,2 @@
1
+ # logstash-filter-example
2
+ Example filter plugin. This should help bootstrap your effort to write your own filter plugin!
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ logstash_path = ENV["LOGSTASH_PATH"] || "../../logstash"
6
+ use_logstash_source = ENV["LOGSTASH_SOURCE"] && ENV["LOGSTASH_SOURCE"].to_s == "1"
7
+
8
+ if Dir.exist?(logstash_path) && use_logstash_source
9
+ gem 'logstash-core', :path => "#{logstash_path}/logstash-core"
10
+ gem 'logstash-core-plugin-api', :path => "#{logstash_path}/logstash-core-plugin-api"
11
+ end
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2012-2018 Elasticsearch <http://www.elastic.co>
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,5 @@
1
+ Elasticsearch
2
+ Copyright 2012-2015 Elasticsearch
3
+
4
+ This product includes software developed by The Apache Software
5
+ Foundation (http://www.apache.org/).
@@ -0,0 +1,98 @@
1
+ # Logstash Plugin
2
+
3
+ [![Travis Build Status](https://travis-ci.org/iqueiroz/logstash-filter-jwt-decoder.svg)](https://travis-ci.org/iqueiroz/logstash-filter-jwt-decoder)
4
+
5
+ This is a plugin for [Logstash](https://github.com/elastic/logstash).
6
+
7
+ It is fully free and fully open source. The license is Apache 2.0, meaning you are pretty much free to use it however you want in whatever way.
8
+
9
+ ## Documentation
10
+
11
+ Logstash provides infrastructure to automatically build documentation for this plugin. We provide a template file, index.asciidoc, where you can add documentation. The contents of this file will be converted into html and then placed with other plugin documentation in a [central location](http://www.elastic.co/guide/en/logstash/current/).
12
+
13
+ - For formatting config examples, you can use the asciidoc `[source,json]` directive
14
+ - For more asciidoc formatting tips, see the excellent reference here https://github.com/elastic/docs#asciidoc-guide
15
+
16
+ ## Need Help?
17
+
18
+ Need help? Try #logstash on freenode IRC or the https://discuss.elastic.co/c/logstash discussion forum.
19
+
20
+ ## Developing
21
+
22
+ ### 1. Plugin Developement and Testing
23
+
24
+ #### Code
25
+ - To get started, you'll need JRuby with the Bundler gem installed.
26
+
27
+ - Create a new plugin or clone and existing from the GitHub [logstash-plugins](https://github.com/logstash-plugins) organization. We also provide [example plugins](https://github.com/logstash-plugins?query=example).
28
+
29
+ - Install dependencies
30
+ ```sh
31
+ bundle install
32
+ ```
33
+
34
+ #### Test
35
+
36
+ - Update your dependencies
37
+
38
+ ```sh
39
+ bundle install
40
+ ```
41
+
42
+ - Run tests
43
+
44
+ ```sh
45
+ bundle exec rspec
46
+ ```
47
+
48
+ ### 2. Running your unpublished Plugin in Logstash
49
+
50
+ #### 2.1 Run in a local Logstash clone
51
+
52
+ - Edit Logstash `Gemfile` and add the local plugin path, for example:
53
+ ```ruby
54
+ gem "logstash-filter-awesome", :path => "/your/local/logstash-filter-awesome"
55
+ ```
56
+ - Install plugin
57
+ ```sh
58
+ # Logstash 2.3 and higher
59
+ bin/logstash-plugin install --no-verify
60
+
61
+ # Prior to Logstash 2.3
62
+ bin/plugin install --no-verify
63
+
64
+ ```
65
+ - Run Logstash with your plugin
66
+ ```sh
67
+ bin/logstash -e 'filter {awesome {}}'
68
+ ```
69
+ At this point any modifications to the plugin code will be applied to this local Logstash setup. After modifying the plugin, simply rerun Logstash.
70
+
71
+ #### 2.2 Run in an installed Logstash
72
+
73
+ You can use the same **2.1** method to run your plugin in an installed Logstash by editing its `Gemfile` and pointing the `:path` to your local plugin development directory or you can build the gem and install it using:
74
+
75
+ - Build your plugin gem
76
+ ```sh
77
+ gem build logstash-filter-awesome.gemspec
78
+ ```
79
+ - Install the plugin from the Logstash home
80
+ ```sh
81
+ # Logstash 2.3 and higher
82
+ bin/logstash-plugin install --no-verify
83
+
84
+ # Prior to Logstash 2.3
85
+ bin/plugin install --no-verify
86
+
87
+ ```
88
+ - Start Logstash and proceed to test the plugin
89
+
90
+ ## Contributing
91
+
92
+ All contributions are welcome: ideas, patches, documentation, bug reports, complaints, and even something you drew up on a napkin.
93
+
94
+ Programming is not a required skill. Whatever you've seen about open source and maintainers or community members saying "send patches or die" - you will not see that here.
95
+
96
+ It is more important to the community that you are able to contribute.
97
+
98
+ For more information about contributing, see the [CONTRIBUTING](https://github.com/elastic/logstash/blob/master/CONTRIBUTING.md) file.
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+ require "logstash/filters/base"
3
+ require "logstash/namespace"
4
+ require "jwt"
5
+ require "jsonpath"
6
+
7
+ class LogStash::Filters::JwtDecoder < LogStash::Filters::Base
8
+
9
+ config_name "jwt_decoder"
10
+
11
+ # The pattern to match the token
12
+ config :token_pattern, :validate => :string, :default => /^[Bb]earer\s+(.+)$/
13
+
14
+ # The capture group index of the matched token
15
+ config :match_group_index, :validate => :number, :default => 0
16
+
17
+ # The path to the access token field
18
+ config :access_token_field, :validate => :string, :default => "message"
19
+
20
+ # The output field
21
+ config :output_field, :validate => :string, :default => "jwt_decoded"
22
+
23
+ # fields to be extracted
24
+ config :extract, :validate => :hash, :default => { "userId" => "$..[0].sub"}
25
+
26
+ public
27
+ def register
28
+ # Add instance variables
29
+ end # def register
30
+
31
+ public
32
+ def filter(event)
33
+ # Replace the event message with our message as configured in the
34
+ # config file.
35
+ raw_message = event.get(@access_token_field)
36
+ if(raw_message)
37
+ if match = raw_message.match(@token_pattern)
38
+ token = match.captures[@match_group_index]
39
+ decoded_token = JWT.decode token, nil, false
40
+
41
+ result = Hash.new
42
+
43
+ @extract.each do |key, value|
44
+ jsonPath = JsonPath.new(value)
45
+ result[key] = jsonPath.first(decoded_token)
46
+ end
47
+
48
+ event.set(@output_field, result)
49
+
50
+ filter_matched(event)
51
+ end
52
+ end
53
+ end # def filter
54
+ end # class LogStash::Filters::JwtDecoder
55
+
@@ -0,0 +1,26 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'logstash-filter-jwt-decoder'
3
+ s.version = '1.0.0'
4
+ s.licenses = ['Apache License (2.0)']
5
+ s.summary = "This plugin allows you to extract any data encoded in a JWT Token that you received in your log."
6
+ s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
7
+ s.authors = ["Ivan de Queiroz"]
8
+ s.email = 'iqueiroz.go@gmail.com'
9
+ s.homepage = "https://github.com/iqueiroz/logstash-filter-jwt-decoder"
10
+ s.require_paths = ["lib"]
11
+
12
+ # Files
13
+ s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE','NOTICE.TXT']
14
+ # Tests
15
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
16
+
17
+ # Special flag to let us know this is actually a logstash plugin
18
+ s.metadata = { "logstash_plugin" => "true", "logstash_group" => "filter" }
19
+
20
+ # Gem dependencies
21
+ s.add_runtime_dependency "logstash-core-plugin-api", "~> 2.0"
22
+ s.add_runtime_dependency 'jwt', "~> 2.1"
23
+ s.add_runtime_dependency 'jsonpath', "~> 0.5"
24
+ s.add_development_dependency 'logstash-devutils'
25
+
26
+ end
@@ -0,0 +1,127 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require "logstash/filters/jwt_decoder"
4
+
5
+ describe LogStash::Filters::JwtDecoder do
6
+
7
+ let(:config) { { } }
8
+ let(:attrs) { { } }
9
+ let(:event) { LogStash::Event.new(attrs) }
10
+
11
+ # Sample JWT from https://jwt.io/
12
+ sampleJwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
13
+
14
+ describe "Empty configuration" do
15
+ let(:config) do <<-CONFIG
16
+ filter {
17
+ jwt_decoder {
18
+ }
19
+ }
20
+ CONFIG
21
+ end
22
+
23
+ context "when jwt field exists" do
24
+ sample("message" => "Bearer #{sampleJwt}") do
25
+ expect(subject.get("jwt_decoded")).to eq({ "userId" => "1234567890" })
26
+ end
27
+ end
28
+
29
+ context "when jwt field does not exists" do
30
+ sample("somefield" => "somevalue") do
31
+ expect(subject.get("jwt_decoded")).to be_nil
32
+ end
33
+ end
34
+ end
35
+
36
+
37
+ describe "With user defined output field" do
38
+ let(:config) do <<-CONFIG
39
+ filter {
40
+ jwt_decoder {
41
+ output_field => "customfield"
42
+ }
43
+ }
44
+ CONFIG
45
+ end
46
+
47
+ context "when jwt field exists" do
48
+ sample("message" => "Bearer #{sampleJwt}") do
49
+ expect(subject.get("customfield")).to eq({ "userId" => "1234567890" })
50
+ end
51
+ end
52
+ end
53
+
54
+ describe "With user defined access token field" do
55
+ let(:config) do <<-CONFIG
56
+ filter {
57
+ jwt_decoder {
58
+ access_token_field => "accesstoken"
59
+ }
60
+ }
61
+ CONFIG
62
+ end
63
+
64
+ context "should be able to decode the token" do
65
+ sample("accesstoken" => "Bearer #{sampleJwt}") do
66
+ expect(subject.get("jwt_decoded")).to eq({ "userId" => "1234567890" })
67
+ end
68
+ end
69
+ end
70
+
71
+ describe "With user defined access token pattern" do
72
+ let(:config) do <<-CONFIG
73
+ filter {
74
+ jwt_decoder {
75
+ token_pattern => "^CustomPrefix\s+(.+)$"
76
+ }
77
+ }
78
+ CONFIG
79
+ end
80
+
81
+ context "should be able to decode the token" do
82
+ sample("message" => "CustomPrefix #{sampleJwt}") do
83
+ expect(subject.get("jwt_decoded")).to eq({ "userId" => "1234567890" })
84
+ end
85
+ end
86
+ end
87
+
88
+ describe "With user defined access token pattern and capture group" do
89
+ let(:config) do <<-CONFIG
90
+ filter {
91
+ jwt_decoder {
92
+ token_pattern => "^(CustomPrefix)(\s+)(.+)$"
93
+ match_group_index => 2
94
+ }
95
+ }
96
+ CONFIG
97
+ end
98
+
99
+ context "should be able to decode the token" do
100
+ sample("message" => "CustomPrefix #{sampleJwt}") do
101
+ expect(subject.get("jwt_decoded")).to eq({ "userId" => "1234567890" })
102
+ end
103
+ end
104
+ end
105
+
106
+
107
+ describe "With multiple fields to be extract" do
108
+ let(:config) do <<-CONFIG
109
+ filter {
110
+ jwt_decoder {
111
+ extract => {
112
+ "userId" => "$..[0].sub"
113
+ "name" => "$..[0].name"
114
+ }
115
+ }
116
+ }
117
+ CONFIG
118
+ end
119
+
120
+ context "should be able to decode the token" do
121
+ sample("message" => "Bearer #{sampleJwt}") do
122
+ expect(subject.get("jwt_decoded")).to eq({ "userId" => "1234567890", "name"=>"John Doe" })
123
+ end
124
+ end
125
+ end
126
+
127
+ end
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-filter-jwt-decoder
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Ivan de Queiroz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-09-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.0'
19
+ name: logstash-core-plugin-api
20
+ prerelease: false
21
+ type: :runtime
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.1'
33
+ name: jwt
34
+ prerelease: false
35
+ type: :runtime
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.1'
41
+ - !ruby/object:Gem::Dependency
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '0.5'
47
+ name: jsonpath
48
+ prerelease: false
49
+ type: :runtime
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.5'
55
+ - !ruby/object:Gem::Dependency
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ name: logstash-devutils
62
+ prerelease: false
63
+ type: :development
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: This gem is a Logstash plugin required to be installed on top of the
70
+ Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This
71
+ gem is not a stand-alone program
72
+ email: iqueiroz.go@gmail.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - CHANGELOG.md
78
+ - CONTRIBUTORS
79
+ - DEVELOPER.md
80
+ - Gemfile
81
+ - LICENSE
82
+ - NOTICE.TXT
83
+ - README.md
84
+ - lib/logstash/filters/jwt_decoder.rb
85
+ - logstash-filter-jwt-decoder.gemspec
86
+ - spec/filters/jwt_decoder_spec.rb
87
+ - spec/spec_helper.rb
88
+ homepage: https://github.com/iqueiroz/logstash-filter-jwt-decoder
89
+ licenses:
90
+ - Apache License (2.0)
91
+ metadata:
92
+ logstash_plugin: 'true'
93
+ logstash_group: filter
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 2.7.6
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: This plugin allows you to extract any data encoded in a JWT Token that you
114
+ received in your log.
115
+ test_files:
116
+ - spec/filters/jwt_decoder_spec.rb
117
+ - spec/spec_helper.rb