├── .gitignore ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── app ├── assets │ ├── config │ │ └── manifest.js │ ├── images │ │ └── .keep │ ├── javascripts │ │ ├── application.js │ │ ├── cable.js │ │ └── channels │ │ │ └── .keep │ └── stylesheets │ │ └── application.scss ├── channels │ └── application_cable │ │ ├── channel.rb │ │ └── connection.rb ├── controllers │ ├── application_controller.rb │ ├── concerns │ │ └── .keep │ ├── main_controller.rb │ ├── session_controller.rb │ └── users_controller.rb ├── helpers │ └── application_helper.rb ├── jobs │ └── application_job.rb ├── mailers │ └── application_mailer.rb ├── models │ ├── application_record.rb │ └── concerns │ │ └── .keep └── views │ ├── layouts │ ├── application.html.erb │ ├── mailer.html.erb │ └── mailer.text.erb │ ├── main │ └── index.html.erb │ ├── session │ ├── forgot_password.erb │ └── new.html.erb │ └── users │ └── new.html.erb ├── bin ├── bundle ├── rails ├── rake ├── setup ├── spring ├── update └── yarn ├── config.ru ├── config ├── application.rb ├── boot.rb ├── cable.yml ├── database.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── application_controller_renderer.rb │ ├── assets.rb │ ├── backtrace_silencers.rb │ ├── cookies_serializer.rb │ ├── filter_parameter_logging.rb │ ├── inflections.rb │ ├── keycloak.rb │ ├── mime_types.rb │ └── wrap_parameters.rb ├── locales │ └── en.yml ├── puma.rb ├── routes.rb ├── secrets.yml └── spring.rb ├── db └── seeds.rb ├── docs ├── client.png ├── forgot_password.png ├── installation.png ├── logout.png ├── main.png ├── my_application.png ├── realm-export.json ├── realm.png ├── realm_email.png ├── role_public.png ├── see_your_email.png ├── service_roles.png ├── sign_up.png ├── user_created.png └── users.png ├── keycloak.json ├── lib ├── assets │ └── .keep └── tasks │ └── .keep ├── log └── .keep ├── package.json ├── public ├── 404.html ├── 422.html ├── 500.html ├── apple-touch-icon-precomposed.png ├── apple-touch-icon.png ├── favicon.ico └── robots.txt ├── test ├── application_system_test_case.rb ├── controllers │ └── .keep ├── fixtures │ ├── .keep │ └── files │ │ └── .keep ├── helpers │ └── .keep ├── integration │ └── .keep ├── mailers │ └── .keep ├── models │ └── .keep ├── system │ └── .keep └── test_helper.rb ├── tmp └── .keep └── vendor └── .keep /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | /db/*.sqlite3-journal 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/* 16 | /tmp/* 17 | !/log/.keep 18 | !/tmp/.keep 19 | 20 | /node_modules 21 | /yarn-error.log 22 | 23 | .byebug_history 24 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | git_source(:github) do |repo_name| 4 | repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") 5 | "https://github.com/#{repo_name}.git" 6 | end 7 | 8 | 9 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 10 | gem 'rails', '~> 5.1.5' 11 | # Use sqlite3 as the database for Active Record 12 | gem 'sqlite3' 13 | # Use Puma as the app server 14 | gem 'puma', '~> 3.7' 15 | # Use SCSS for stylesheets 16 | gem 'sass-rails', '~> 5.0' 17 | # Use Uglifier as compressor for JavaScript assets 18 | gem 'uglifier', '>= 1.3.0' 19 | # See https://github.com/rails/execjs#readme for more supported runtimes 20 | # gem 'therubyracer', platforms: :ruby 21 | 22 | # Use CoffeeScript for .coffee assets and views 23 | gem 'coffee-rails', '~> 4.2' 24 | # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks 25 | gem 'turbolinks', '~> 5' 26 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 27 | gem 'jbuilder', '~> 2.5' 28 | # Use Redis adapter to run Action Cable in production 29 | # gem 'redis', '~> 4.0' 30 | # Use ActiveModel has_secure_password 31 | # gem 'bcrypt', '~> 3.1.7' 32 | 33 | # Use Capistrano for deployment 34 | # gem 'capistrano-rails', group: :development 35 | 36 | group :development, :test do 37 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console 38 | gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] 39 | # Adds support for Capybara system testing and selenium driver 40 | gem 'capybara', '~> 2.13' 41 | gem 'selenium-webdriver' 42 | end 43 | 44 | group :development do 45 | # Access an IRB console on exception pages or by using <%= console %> anywhere in the code. 46 | gem 'web-console', '>= 3.3.0' 47 | gem 'listen', '>= 3.0.5', '< 3.2' 48 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 49 | gem 'spring' 50 | gem 'spring-watcher-listen', '~> 2.0.0' 51 | end 52 | 53 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 54 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 55 | 56 | # Add authentication to applications and secure services with Keycloak 57 | gem 'keycloak', '~> 2.3', '>= 2.3.2' 58 | 59 | # This gem overrides Rails' UJS behaviour to open up a Bootstrap Modal instead of the browser's built in confirm() dialog 60 | gem 'data-confirm-modal' 61 | 62 | # Use jquery as the JavaScript library 63 | gem 'jquery-rails' 64 | 65 | # jQuery UI's JavaScript, CSS, and image files packaged for the Rails 3.1+ asset pipeline 66 | gem 'jquery-ui-rails' 67 | 68 | # Bootstrap 69 | gem 'bootstrap-sass', '3.3.7' 70 | gem 'bootstrap-slider-rails', '9.2.0' 71 | gem 'bootstrap-table-rails', '1.11.1.1' 72 | gem 'bootstrap_form', '2.6.0' 73 | gem 'bootstrap-validator-rails', '~> 0.5.3' 74 | 75 | gem 'autoprefixer-rails' -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | actioncable (5.1.6) 5 | actionpack (= 5.1.6) 6 | nio4r (~> 2.0) 7 | websocket-driver (~> 0.6.1) 8 | actionmailer (5.1.6) 9 | actionpack (= 5.1.6) 10 | actionview (= 5.1.6) 11 | activejob (= 5.1.6) 12 | mail (~> 2.5, >= 2.5.4) 13 | rails-dom-testing (~> 2.0) 14 | actionpack (5.1.6) 15 | actionview (= 5.1.6) 16 | activesupport (= 5.1.6) 17 | rack (~> 2.0) 18 | rack-test (>= 0.6.3) 19 | rails-dom-testing (~> 2.0) 20 | rails-html-sanitizer (~> 1.0, >= 1.0.2) 21 | actionview (5.1.6) 22 | activesupport (= 5.1.6) 23 | builder (~> 3.1) 24 | erubi (~> 1.4) 25 | rails-dom-testing (~> 2.0) 26 | rails-html-sanitizer (~> 1.0, >= 1.0.3) 27 | activejob (5.1.6) 28 | activesupport (= 5.1.6) 29 | globalid (>= 0.3.6) 30 | activemodel (5.1.6) 31 | activesupport (= 5.1.6) 32 | activerecord (5.1.6) 33 | activemodel (= 5.1.6) 34 | activesupport (= 5.1.6) 35 | arel (~> 8.0) 36 | activesupport (5.1.6) 37 | concurrent-ruby (~> 1.0, >= 1.0.2) 38 | i18n (>= 0.7, < 2) 39 | minitest (~> 5.1) 40 | tzinfo (~> 1.1) 41 | addressable (2.5.2) 42 | public_suffix (>= 2.0.2, < 4.0) 43 | arel (8.0.0) 44 | autoprefixer-rails (8.2.0) 45 | execjs 46 | bindex (0.5.0) 47 | bootstrap-sass (3.3.7) 48 | autoprefixer-rails (>= 5.2.1) 49 | sass (>= 3.3.4) 50 | bootstrap-slider-rails (9.2.0) 51 | railties (>= 3.2, < 6.0) 52 | bootstrap-table-rails (1.11.1.1) 53 | bootstrap-validator-rails (0.5.3) 54 | jquery-rails (>= 3.0) 55 | railties (>= 3.0) 56 | bootstrap_form (2.6.0) 57 | builder (3.2.3) 58 | byebug (10.0.2) 59 | capybara (2.18.0) 60 | addressable 61 | mini_mime (>= 0.1.3) 62 | nokogiri (>= 1.3.3) 63 | rack (>= 1.0.0) 64 | rack-test (>= 0.5.4) 65 | xpath (>= 2.0, < 4.0) 66 | childprocess (0.9.0) 67 | ffi (~> 1.0, >= 1.0.11) 68 | coffee-rails (4.2.2) 69 | coffee-script (>= 2.2.0) 70 | railties (>= 4.0.0) 71 | coffee-script (2.4.1) 72 | coffee-script-source 73 | execjs 74 | coffee-script-source (1.12.2) 75 | concurrent-ruby (1.0.5) 76 | crass (1.0.4) 77 | data-confirm-modal (1.6.2) 78 | railties (>= 3.0) 79 | domain_name (0.5.20170404) 80 | unf (>= 0.0.5, < 1.0.0) 81 | erubi (1.7.1) 82 | execjs (2.7.0) 83 | ffi (1.9.23) 84 | globalid (0.4.1) 85 | activesupport (>= 4.2.0) 86 | http-cookie (1.0.3) 87 | domain_name (~> 0.5) 88 | i18n (1.0.0) 89 | concurrent-ruby (~> 1.0) 90 | jbuilder (2.7.0) 91 | activesupport (>= 4.2.0) 92 | multi_json (>= 1.2) 93 | jquery-rails (4.3.1) 94 | rails-dom-testing (>= 1, < 3) 95 | railties (>= 4.2.0) 96 | thor (>= 0.14, < 2.0) 97 | jquery-ui-rails (6.0.1) 98 | railties (>= 3.2.16) 99 | json (2.1.0) 100 | jwt (2.1.0) 101 | keycloak (2.3.2) 102 | json 103 | jwt 104 | rest-client 105 | listen (3.1.5) 106 | rb-fsevent (~> 0.9, >= 0.9.4) 107 | rb-inotify (~> 0.9, >= 0.9.7) 108 | ruby_dep (~> 1.2) 109 | loofah (2.2.2) 110 | crass (~> 1.0.2) 111 | nokogiri (>= 1.5.9) 112 | mail (2.7.0) 113 | mini_mime (>= 0.1.1) 114 | method_source (0.9.0) 115 | mime-types (3.1) 116 | mime-types-data (~> 3.2015) 117 | mime-types-data (3.2016.0521) 118 | mini_mime (1.0.0) 119 | mini_portile2 (2.3.0) 120 | minitest (5.11.3) 121 | multi_json (1.13.1) 122 | netrc (0.11.0) 123 | nio4r (2.3.0) 124 | nokogiri (1.8.2) 125 | mini_portile2 (~> 2.3.0) 126 | public_suffix (3.0.2) 127 | puma (3.11.4) 128 | rack (2.0.4) 129 | rack-test (1.0.0) 130 | rack (>= 1.0, < 3) 131 | rails (5.1.6) 132 | actioncable (= 5.1.6) 133 | actionmailer (= 5.1.6) 134 | actionpack (= 5.1.6) 135 | actionview (= 5.1.6) 136 | activejob (= 5.1.6) 137 | activemodel (= 5.1.6) 138 | activerecord (= 5.1.6) 139 | activesupport (= 5.1.6) 140 | bundler (>= 1.3.0) 141 | railties (= 5.1.6) 142 | sprockets-rails (>= 2.0.0) 143 | rails-dom-testing (2.0.3) 144 | activesupport (>= 4.2.0) 145 | nokogiri (>= 1.6) 146 | rails-html-sanitizer (1.0.4) 147 | loofah (~> 2.2, >= 2.2.2) 148 | railties (5.1.6) 149 | actionpack (= 5.1.6) 150 | activesupport (= 5.1.6) 151 | method_source 152 | rake (>= 0.8.7) 153 | thor (>= 0.18.1, < 2.0) 154 | rake (12.3.1) 155 | rb-fsevent (0.10.3) 156 | rb-inotify (0.9.10) 157 | ffi (>= 0.5.0, < 2) 158 | rest-client (2.0.2) 159 | http-cookie (>= 1.0.2, < 2.0) 160 | mime-types (>= 1.16, < 4.0) 161 | netrc (~> 0.8) 162 | ruby_dep (1.5.0) 163 | rubyzip (1.2.1) 164 | sass (3.5.6) 165 | sass-listen (~> 4.0.0) 166 | sass-listen (4.0.0) 167 | rb-fsevent (~> 0.9, >= 0.9.4) 168 | rb-inotify (~> 0.9, >= 0.9.7) 169 | sass-rails (5.0.7) 170 | railties (>= 4.0.0, < 6) 171 | sass (~> 3.1) 172 | sprockets (>= 2.8, < 4.0) 173 | sprockets-rails (>= 2.0, < 4.0) 174 | tilt (>= 1.1, < 3) 175 | selenium-webdriver (3.11.0) 176 | childprocess (~> 0.5) 177 | rubyzip (~> 1.2) 178 | spring (2.0.2) 179 | activesupport (>= 4.2) 180 | spring-watcher-listen (2.0.1) 181 | listen (>= 2.7, < 4.0) 182 | spring (>= 1.2, < 3.0) 183 | sprockets (3.7.1) 184 | concurrent-ruby (~> 1.0) 185 | rack (> 1, < 3) 186 | sprockets-rails (3.2.1) 187 | actionpack (>= 4.0) 188 | activesupport (>= 4.0) 189 | sprockets (>= 3.0.0) 190 | sqlite3 (1.3.13) 191 | thor (0.20.0) 192 | thread_safe (0.3.6) 193 | tilt (2.0.8) 194 | turbolinks (5.1.1) 195 | turbolinks-source (~> 5.1) 196 | turbolinks-source (5.1.0) 197 | tzinfo (1.2.5) 198 | thread_safe (~> 0.1) 199 | uglifier (4.1.9) 200 | execjs (>= 0.3.0, < 3) 201 | unf (0.1.4) 202 | unf_ext 203 | unf_ext (0.0.7.5) 204 | web-console (3.6.0) 205 | actionview (>= 5.0) 206 | activemodel (>= 5.0) 207 | bindex (>= 0.4.0) 208 | railties (>= 5.0) 209 | websocket-driver (0.6.5) 210 | websocket-extensions (>= 0.1.0) 211 | websocket-extensions (0.1.3) 212 | xpath (3.0.0) 213 | nokogiri (~> 1.8) 214 | 215 | PLATFORMS 216 | ruby 217 | 218 | DEPENDENCIES 219 | autoprefixer-rails 220 | bootstrap-sass (= 3.3.7) 221 | bootstrap-slider-rails (= 9.2.0) 222 | bootstrap-table-rails (= 1.11.1.1) 223 | bootstrap-validator-rails (~> 0.5.3) 224 | bootstrap_form (= 2.6.0) 225 | byebug 226 | capybara (~> 2.13) 227 | coffee-rails (~> 4.2) 228 | data-confirm-modal 229 | jbuilder (~> 2.5) 230 | jquery-rails 231 | jquery-ui-rails 232 | keycloak (~> 2.3, >= 2.3.2) 233 | listen (>= 3.0.5, < 3.2) 234 | puma (~> 3.7) 235 | rails (~> 5.1.5) 236 | sass-rails (~> 5.0) 237 | selenium-webdriver 238 | spring 239 | spring-watcher-listen (~> 2.0.0) 240 | sqlite3 241 | turbolinks (~> 5) 242 | tzinfo-data 243 | uglifier (>= 1.3.0) 244 | web-console (>= 3.3.0) 245 | 246 | BUNDLED WITH 247 | 1.16.1 248 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gem Keycloak - example 2 | 3 | ## Versions 4 | 5 | * ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux] 6 | * Rails 5.1.6 7 | * gem 'keycloak', '~> 2.3', '>= 2.3.2' 8 | 9 | --- 10 | ## Description 11 | 12 | This is a simple example of how to build an application using [gem Keycloak](https://github.com/imagov/keycloak) and using the views from your own application. 13 | 14 | ## Step by Step 15 | 16 | **1.** Clone this project 17 | 18 | **2.** Create a new realm: 19 | 20 | ![Alt text](docs/realm.png "New Realm") 21 | 22 | **3.** Configure a email to send then "forgot password" email: 23 | 24 | ![Alt text](docs/realm_email.png "Email Configuration") 25 | 26 | **4.** Create a new client in the realm: 27 | 28 | ![Alt text](docs/client.png "New Client") 29 | 30 | **5.** Create a new role in the client: 31 | 32 | ![Alt text](docs/role_public.png "Public Role") 33 | 34 | **6.** Export installation.json file and paste in application folder. The gem will get client information at this file.: 35 | 36 | ![Alt text](docs/installation.png "installation.json") 37 | 38 | **7.** Install application gems: 39 | 40 | ``` 41 | $ bundle 42 | ``` 43 | 44 | **8.** Create database: 45 | 46 | ``` 47 | $ rails db:create 48 | $ rails db:migrate 49 | ``` 50 | 51 | **9.** Start application: 52 | 53 | ``` 54 | $ rails s 55 | ``` 56 | 57 | **10.** [Access application](http://localhost:3000/) 58 | 59 | ![Alt text](docs/my_application.png "Application") 60 | 61 | **11.** Create a new user: 62 | 63 | ![Alt text](docs/sign_up.png "Sign Up") 64 | ![Alt text](docs/user_created.png "User created") 65 | 66 | **12.** See the new user in Keycloak: 67 | 68 | ![Alt text](docs/users.png "Users") 69 | 70 | **13.** Sign In and access the main screen: 71 | 72 | ![Alt text](docs/main.png "Main screen") 73 | 74 | **14.** Click in "Logout": 75 | 76 | ![Alt text](docs/logout.png "Logout") 77 | 78 | **15.** Click in "Logout": 79 | 80 | ![Alt text](docs/logout.png "Logout") 81 | 82 | **16.** Click in "I forgot my password": 83 | 84 | ![Alt text](docs/forgot_password.png "forgot password") 85 | 86 | **17.** See your email: 87 | 88 | ![Alt text](docs/see_your_email.png "See your email") 89 | 90 | **In [docs](https://github.com/imagov/example-gem-keycloak/tree/master/docs) folder there are the realm file exported and all images of this documentation.** -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative 'config/application' 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../javascripts .js 3 | //= link_directory ../stylesheets .css 4 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/app/assets/images/.keep -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's 5 | // vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. JavaScript code in this file should be added after the last require_* statement. 9 | // 10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require jquery 14 | //= require jquery_ujs 15 | //= require bootstrap 16 | //= require bootstrap-slider 17 | //= require bootstrapValidator.min 18 | //= require rails-ujs 19 | //= require data-confirm-modal 20 | //= require turbolinks 21 | //= require bootstrap-sprockets 22 | //= require_tree . 23 | -------------------------------------------------------------------------------- /app/assets/javascripts/cable.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | // 4 | //= require action_cable 5 | //= require_self 6 | //= require_tree ./channels 7 | 8 | (function() { 9 | this.App || (this.App = {}); 10 | 11 | App.cable = ActionCable.createConsumer(); 12 | 13 | }).call(this); 14 | -------------------------------------------------------------------------------- /app/assets/javascripts/channels/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/app/assets/javascripts/channels/.keep -------------------------------------------------------------------------------- /app/assets/stylesheets/application.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's 6 | * vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS 10 | * files in this directory. Styles in this file should be added after the last require_* statement. 11 | * It is generally better to create a new file per style scope. 12 | * 13 | *= require rails_bootstrap_forms 14 | *= require bootstrapValidator.min 15 | *= require bootstrap-table 16 | *= require bootstrap-slider 17 | *= require_tree . 18 | *= require_self 19 | */ 20 | 21 | @import "bootstrap-sprockets"; 22 | @import "bootstrap"; 23 | -------------------------------------------------------------------------------- /app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | # application controller 2 | class ApplicationController < ActionController::Base 3 | protect_from_forgery with: :exception 4 | before_action :user_signed_in? 5 | 6 | def initialize 7 | Keycloak.proc_cookie_token = lambda do 8 | cookies.permanent[:keycloak_token] 9 | end 10 | 11 | super 12 | end 13 | 14 | def user_signed_in? 15 | access = Keycloak::Client.user_signed_in? || keycloak_controller? || new_use? 16 | redirect_to session_new_path unless access 17 | end 18 | 19 | private 20 | 21 | def keycloak_controller? 22 | Keycloak.keycloak_controller == controller_name 23 | end 24 | 25 | def new_use? 26 | controller_name == 'users' && (action_name == "new" || action_name == "create") 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /app/controllers/main_controller.rb: -------------------------------------------------------------------------------- 1 | # main controller 2 | class MainController < ApplicationController 3 | def index 4 | @user = JSON.parse Keycloak::Client.get_userinfo 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/controllers/session_controller.rb: -------------------------------------------------------------------------------- 1 | # Authentication 2 | class SessionController < ApplicationController 3 | def new; end 4 | 5 | def signin 6 | cookies.permanent[:keycloak_token] = Keycloak::Client.get_token params[:email], params[:password] 7 | redirect_to root_path if Keycloak::Client.user_signed_in? 8 | end 9 | 10 | def logout 11 | flash[:success] = 'See you later' if Keycloak::Client.logout 12 | redirect_to root_path 13 | end 14 | 15 | def forgot_password; end 16 | 17 | def reset_password 18 | Keycloak::Internal.forgot_password params[:email], root_path 19 | flash[:success] = 'Please take a look at your email' 20 | redirect_to root_path 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /app/controllers/users_controller.rb: -------------------------------------------------------------------------------- 1 | # user controller 2 | class UsersController < ApplicationController 3 | def new; end 4 | 5 | def create 6 | after_insert = lambda { |_user| 7 | flash[:success] = 'User created successfully' 8 | redirect_to root_path 9 | } 10 | 11 | Keycloak::Internal.create_simple_user(params[:email], 12 | params[:password], 13 | params[:email], 14 | params[:first_name], 15 | params[:last_name], 16 | [], 17 | ['Public'], 18 | after_insert) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | end 3 | -------------------------------------------------------------------------------- /app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/app/models/concerns/.keep -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MyApplication 5 | <%= csrf_meta_tags %> 6 | 7 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> 8 | <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> 9 | 10 | 11 | 12 | 13 | <% if notice %> 14 |
15 | 16 | <%= notice %> 17 |
18 | <% end %> 19 | 20 | <% flash.each do |type, message| %> 21 | <% if type == 'success' %> 22 |
23 | 24 | <%= message %> 25 |
26 | <% else %> 27 |
28 | 29 | <%= message %> 30 |
31 | <% end %> 32 | <% end %> 33 | 34 | <%= yield %> 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /app/views/main/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Hello, <%=@user['name'] %>

3 |
4 |
5 |
6 | <%= link_to("Logout", session_logout_path, method: :delete) %> 7 |
8 |
-------------------------------------------------------------------------------- /app/views/session/forgot_password.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | 23 |
24 |
25 | -------------------------------------------------------------------------------- /app/views/session/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | 32 |
33 |
34 | -------------------------------------------------------------------------------- /app/views/users/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Sign Up

4 |
5 |
6 |
7 | <%= bootstrap_form_tag url: users_path, method: :post do |f| %> 8 | 9 | <%= f.text_field :first_name, autofocus: true %> 10 | <%= f.text_field :last_name %> 11 | <%= f.email_field :email, autocomplete: "off" %> 12 | <%= f.password_field :password, autocomplete: "off", placeholder: 'Passowrd'%> 13 | <%= f.password_field :password_confirmation, autocomplete: "off", placeholder: 'Confirm your password' %> 14 | 15 | <%= f.submit "Sign Up", class:"btn btn-primary" %> 16 | <% end %> 17 |
18 |
19 |
-------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | APP_PATH = File.expand_path('../config/application', __dir__) 8 | require_relative '../config/boot' 9 | require 'rails/commands' 10 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require_relative '../config/boot' 8 | require 'rake' 9 | Rake.application.run 10 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | require 'fileutils' 4 | include FileUtils 5 | 6 | # path to your application root. 7 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 8 | 9 | def system!(*args) 10 | system(*args) || abort("\n== Command #{args} failed ==") 11 | end 12 | 13 | chdir APP_ROOT do 14 | # This script is a starting point to setup your application. 15 | # Add necessary setup steps to this file. 16 | 17 | puts '== Installing dependencies ==' 18 | system! 'gem install bundler --conservative' 19 | system('bundle check') || system!('bundle install') 20 | 21 | # Install JavaScript dependencies if using Yarn 22 | # system('bin/yarn') 23 | 24 | 25 | # puts "\n== Copying sample files ==" 26 | # unless File.exist?('config/database.yml') 27 | # cp 'config/database.yml.sample', 'config/database.yml' 28 | # end 29 | 30 | puts "\n== Preparing database ==" 31 | system! 'bin/rails db:setup' 32 | 33 | puts "\n== Removing old logs and tempfiles ==" 34 | system! 'bin/rails log:clear tmp:clear' 35 | 36 | puts "\n== Restarting application server ==" 37 | system! 'bin/rails restart' 38 | end 39 | -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast. 4 | # It gets overwritten when you run the `spring binstub` command. 5 | 6 | unless defined?(Spring) 7 | require 'rubygems' 8 | require 'bundler' 9 | 10 | lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read) 11 | spring = lockfile.specs.detect { |spec| spec.name == "spring" } 12 | if spring 13 | Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path 14 | gem 'spring', spring.version 15 | require 'spring/binstub' 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /bin/update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | require 'fileutils' 4 | include FileUtils 5 | 6 | # path to your application root. 7 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 8 | 9 | def system!(*args) 10 | system(*args) || abort("\n== Command #{args} failed ==") 11 | end 12 | 13 | chdir APP_ROOT do 14 | # This script is a way to update your development environment automatically. 15 | # Add necessary update steps to this file. 16 | 17 | puts '== Installing dependencies ==' 18 | system! 'gem install bundler --conservative' 19 | system('bundle check') || system!('bundle install') 20 | 21 | puts "\n== Updating database ==" 22 | system! 'bin/rails db:migrate' 23 | 24 | puts "\n== Removing old logs and tempfiles ==" 25 | system! 'bin/rails log:clear tmp:clear' 26 | 27 | puts "\n== Restarting application server ==" 28 | system! 'bin/rails restart' 29 | end 30 | -------------------------------------------------------------------------------- /bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | VENDOR_PATH = File.expand_path('..', __dir__) 3 | Dir.chdir(VENDOR_PATH) do 4 | begin 5 | exec "yarnpkg #{ARGV.join(" ")}" 6 | rescue Errno::ENOENT 7 | $stderr.puts "Yarn executable was not detected in the system." 8 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 9 | exit 1 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative 'config/environment' 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative 'boot' 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module MyApplication 10 | class Application < Rails::Application 11 | # Initialize configuration defaults for originally generated Rails version. 12 | config.load_defaults 5.1 13 | 14 | # Settings in config/environments/* take precedence over those specified here. 15 | # Application configuration should go into files in config/initializers 16 | # -- all .rb files in that directory are automatically loaded. 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: async 6 | 7 | production: 8 | adapter: redis 9 | url: redis://localhost:6379/1 10 | channel_prefix: my_application_production 11 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | # 7 | default: &default 8 | adapter: sqlite3 9 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 10 | timeout: 5000 11 | 12 | development: 13 | <<: *default 14 | database: db/development.sqlite3 15 | 16 | # Warning: The database defined as "test" will be erased and 17 | # re-generated from your development database when you run "rake". 18 | # Do not set this db to the same as development or production. 19 | test: 20 | <<: *default 21 | database: db/test.sqlite3 22 | 23 | production: 24 | <<: *default 25 | database: db/production.sqlite3 26 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative 'application' 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports. 13 | config.consider_all_requests_local = true 14 | 15 | # Enable/disable caching. By default caching is disabled. 16 | if Rails.root.join('tmp/caching-dev.txt').exist? 17 | config.action_controller.perform_caching = true 18 | 19 | config.cache_store = :memory_store 20 | config.public_file_server.headers = { 21 | 'Cache-Control' => "public, max-age=#{2.days.seconds.to_i}" 22 | } 23 | else 24 | config.action_controller.perform_caching = false 25 | 26 | config.cache_store = :null_store 27 | end 28 | 29 | # Don't care if the mailer can't send. 30 | config.action_mailer.raise_delivery_errors = false 31 | 32 | config.action_mailer.perform_caching = false 33 | 34 | # Print deprecation notices to the Rails logger. 35 | config.active_support.deprecation = :log 36 | 37 | # Raise an error on page load if there are pending migrations. 38 | config.active_record.migration_error = :page_load 39 | 40 | # Debug mode disables concatenation and preprocessing of assets. 41 | # This option may cause significant delays in view rendering with a large 42 | # number of complex assets. 43 | config.assets.debug = true 44 | 45 | # Suppress logger output for asset requests. 46 | config.assets.quiet = true 47 | 48 | # Raises error for missing translations 49 | # config.action_view.raise_on_missing_translations = true 50 | 51 | # Use an evented file watcher to asynchronously detect changes in source code, 52 | # routes, locales, etc. This feature depends on the listen gem. 53 | config.file_watcher = ActiveSupport::EventedFileUpdateChecker 54 | end 55 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both threaded web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Attempt to read encrypted secrets from `config/secrets.yml.enc`. 18 | # Requires an encryption key in `ENV["RAILS_MASTER_KEY"]` or 19 | # `config/secrets.yml.key`. 20 | config.read_encrypted_secrets = true 21 | 22 | # Disable serving static files from the `/public` folder by default since 23 | # Apache or NGINX already handles this. 24 | config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? 25 | 26 | # Compress JavaScripts and CSS. 27 | config.assets.js_compressor = :uglifier 28 | # config.assets.css_compressor = :sass 29 | 30 | # Do not fallback to assets pipeline if a precompiled asset is missed. 31 | config.assets.compile = false 32 | 33 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 34 | 35 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 36 | # config.action_controller.asset_host = 'http://assets.example.com' 37 | 38 | # Specifies the header that your server uses for sending files. 39 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 40 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 41 | 42 | # Mount Action Cable outside main process or domain 43 | # config.action_cable.mount_path = nil 44 | # config.action_cable.url = 'wss://example.com/cable' 45 | # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] 46 | 47 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 48 | # config.force_ssl = true 49 | 50 | # Use the lowest log level to ensure availability of diagnostic information 51 | # when problems arise. 52 | config.log_level = :debug 53 | 54 | # Prepend all log lines with the following tags. 55 | config.log_tags = [ :request_id ] 56 | 57 | # Use a different cache store in production. 58 | # config.cache_store = :mem_cache_store 59 | 60 | # Use a real queuing backend for Active Job (and separate queues per environment) 61 | # config.active_job.queue_adapter = :resque 62 | # config.active_job.queue_name_prefix = "my_application_#{Rails.env}" 63 | config.action_mailer.perform_caching = false 64 | 65 | # Ignore bad email addresses and do not raise email delivery errors. 66 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 67 | # config.action_mailer.raise_delivery_errors = false 68 | 69 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 70 | # the I18n.default_locale when a translation cannot be found). 71 | config.i18n.fallbacks = true 72 | 73 | # Send deprecation notices to registered listeners. 74 | config.active_support.deprecation = :notify 75 | 76 | # Use default logging formatter so that PID and timestamp are not suppressed. 77 | config.log_formatter = ::Logger::Formatter.new 78 | 79 | # Use a different logger for distributed setups. 80 | # require 'syslog/logger' 81 | # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') 82 | 83 | if ENV["RAILS_LOG_TO_STDOUT"].present? 84 | logger = ActiveSupport::Logger.new(STDOUT) 85 | logger.formatter = config.log_formatter 86 | config.logger = ActiveSupport::TaggedLogging.new(logger) 87 | end 88 | 89 | # Do not dump schema after migrations. 90 | config.active_record.dump_schema_after_migration = false 91 | end 92 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure public file server for tests with Cache-Control for performance. 16 | config.public_file_server.enabled = true 17 | config.public_file_server.headers = { 18 | 'Cache-Control' => "public, max-age=#{1.hour.seconds.to_i}" 19 | } 20 | 21 | # Show full error reports and disable caching. 22 | config.consider_all_requests_local = true 23 | config.action_controller.perform_caching = false 24 | 25 | # Raise exceptions instead of rendering exception templates. 26 | config.action_dispatch.show_exceptions = false 27 | 28 | # Disable request forgery protection in test environment. 29 | config.action_controller.allow_forgery_protection = false 30 | config.action_mailer.perform_caching = false 31 | 32 | # Tell Action Mailer not to deliver emails to the real world. 33 | # The :test delivery method accumulates sent emails in the 34 | # ActionMailer::Base.deliveries array. 35 | config.action_mailer.delivery_method = :test 36 | 37 | # Print deprecation notices to the stderr. 38 | config.active_support.deprecation = :stderr 39 | 40 | # Raises error for missing translations 41 | # config.action_view.raise_on_missing_translations = true 42 | end 43 | -------------------------------------------------------------------------------- /config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path. 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | # Add Yarn node_modules folder to the asset load path. 9 | Rails.application.config.assets.paths << Rails.root.join('node_modules') 10 | 11 | # Precompile additional assets. 12 | # application.js, application.css, and all non-JS/CSS in the app/assets 13 | # folder are already added. 14 | # Rails.application.config.assets.precompile += %w( admin.js admin.css ) 15 | 16 | # Rails.application.config.assets.precompile += %w[] 17 | 18 | # Rails.application.config.assets.precompile += %w[jquery.js 19 | # jquery_ujs.js 20 | # turbolinks.js 21 | # bootstrap.js] 22 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/initializers/keycloak.rb: -------------------------------------------------------------------------------- 1 | # Set proxy to connect in keycloak server 2 | Keycloak.proxy = '' 3 | # If true, then all request exception will explode in application (this is the default value) 4 | Keycloak.generate_request_exception = true 5 | # controller that manage the user session 6 | Keycloak.keycloak_controller = 'session' 7 | # relm name (only if the installation file is not present) 8 | Keycloak.realm = '' 9 | # relm url (only if the installation file is not present) 10 | Keycloak.auth_server_url = '' -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # The following keys must be escaped otherwise they will not be retrieved by 20 | # the default I18n backend: 21 | # 22 | # true, false, on, off, yes, no 23 | # 24 | # Instead, surround them with single quotes. 25 | # 26 | # en: 27 | # 'true': 'foo' 28 | # 29 | # To learn more, please read the Rails Internationalization guide 30 | # available at http://guides.rubyonrails.org/i18n.html. 31 | 32 | en: 33 | hello: "Hello world" 34 | -------------------------------------------------------------------------------- /config/puma.rb: -------------------------------------------------------------------------------- 1 | # Puma can serve each request in a thread from an internal thread pool. 2 | # The `threads` method setting takes two numbers: a minimum and maximum. 3 | # Any libraries that use thread pools should be configured to match 4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum 5 | # and maximum; this matches the default thread size of Active Record. 6 | # 7 | threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 8 | threads threads_count, threads_count 9 | 10 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000. 11 | # 12 | port ENV.fetch("PORT") { 3000 } 13 | 14 | # Specifies the `environment` that Puma will run in. 15 | # 16 | environment ENV.fetch("RAILS_ENV") { "development" } 17 | 18 | # Specifies the number of `workers` to boot in clustered mode. 19 | # Workers are forked webserver processes. If using threads and workers together 20 | # the concurrency of the application would be max `threads` * `workers`. 21 | # Workers do not work on JRuby or Windows (both of which do not support 22 | # processes). 23 | # 24 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 } 25 | 26 | # Use the `preload_app!` method when specifying a `workers` number. 27 | # This directive tells Puma to first boot the application and load code 28 | # before forking the application. This takes advantage of Copy On Write 29 | # process behavior so workers use less memory. If you use this option 30 | # you need to make sure to reconnect any threads in the `on_worker_boot` 31 | # block. 32 | # 33 | # preload_app! 34 | 35 | # If you are preloading your application and using Active Record, it's 36 | # recommended that you close any connections to the database before workers 37 | # are forked to prevent connection leakage. 38 | # 39 | # before_fork do 40 | # ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord) 41 | # end 42 | 43 | # The code in the `on_worker_boot` will be called if you are using 44 | # clustered mode by specifying a number of `workers`. After each worker 45 | # process is booted, this block will be run. If you are using the `preload_app!` 46 | # option, you will want to use this block to reconnect to any threads 47 | # or connections that may have been created at application boot, as Ruby 48 | # cannot share connections between processes. 49 | # 50 | # on_worker_boot do 51 | # ActiveRecord::Base.establish_connection if defined?(ActiveRecord) 52 | # end 53 | # 54 | 55 | # Allow puma to be restarted by `rails restart` command. 56 | plugin :tmp_restart 57 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | get 'session/new' 3 | post 'session/signin' 4 | delete 'session/logout' 5 | get 'session/forgot_password' 6 | put 'session/reset_password' 7 | 8 | resources :users, only: [:new, :create] 9 | 10 | root 'main#index' 11 | end 12 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rails secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | # Shared secrets are available across all environments. 14 | 15 | # shared: 16 | # api_key: a1B2c3D4e5F6 17 | 18 | # Environmental secrets are only available for that specific environment. 19 | 20 | development: 21 | secret_key_base: 8814129567b98025039f3715048f10ea6dd179aba99b917b72259c2657f88be118b325a060a4c892d2160e3d5126c110cafd96351b1d8d69376f39f24439b104 22 | 23 | test: 24 | secret_key_base: ae4b883f5b954bf8ef86f79f9cf2a369da97e6653119cdd081de75743007188bb6b1bcf7b0886ef6f56939702aed954e181a8463b4e62e53f8db81cedc127a01 25 | 26 | # Do not keep production secrets in the unencrypted secrets file. 27 | # Instead, either read values from the environment. 28 | # Or, use `bin/rails secrets:setup` to configure encrypted secrets 29 | # and move the `production:` environment over there. 30 | 31 | production: 32 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 33 | -------------------------------------------------------------------------------- /config/spring.rb: -------------------------------------------------------------------------------- 1 | %w( 2 | .ruby-version 3 | .rbenv-vars 4 | tmp/restart.txt 5 | tmp/caching-dev.txt 6 | ).each { |path| Spring.watch(path) } 7 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) 7 | # Character.create(name: 'Luke', movie: movies.first) 8 | -------------------------------------------------------------------------------- /docs/client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/docs/client.png -------------------------------------------------------------------------------- /docs/forgot_password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/docs/forgot_password.png -------------------------------------------------------------------------------- /docs/installation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/docs/installation.png -------------------------------------------------------------------------------- /docs/logout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/docs/logout.png -------------------------------------------------------------------------------- /docs/main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/docs/main.png -------------------------------------------------------------------------------- /docs/my_application.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/docs/my_application.png -------------------------------------------------------------------------------- /docs/realm-export.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "realm_gem", 3 | "realm": "realm_gem", 4 | "notBefore": 0, 5 | "revokeRefreshToken": false, 6 | "refreshTokenMaxReuse": 0, 7 | "accessTokenLifespan": 300, 8 | "accessTokenLifespanForImplicitFlow": 900, 9 | "ssoSessionIdleTimeout": 1800, 10 | "ssoSessionMaxLifespan": 36000, 11 | "offlineSessionIdleTimeout": 2592000, 12 | "accessCodeLifespan": 60, 13 | "accessCodeLifespanUserAction": 300, 14 | "accessCodeLifespanLogin": 1800, 15 | "actionTokenGeneratedByAdminLifespan": 43200, 16 | "actionTokenGeneratedByUserLifespan": 300, 17 | "enabled": true, 18 | "sslRequired": "external", 19 | "registrationAllowed": false, 20 | "registrationEmailAsUsername": false, 21 | "rememberMe": false, 22 | "verifyEmail": false, 23 | "loginWithEmailAllowed": true, 24 | "duplicateEmailsAllowed": false, 25 | "resetPasswordAllowed": false, 26 | "editUsernameAllowed": false, 27 | "bruteForceProtected": false, 28 | "permanentLockout": false, 29 | "maxFailureWaitSeconds": 900, 30 | "minimumQuickLoginWaitSeconds": 60, 31 | "waitIncrementSeconds": 60, 32 | "quickLoginCheckMilliSeconds": 1000, 33 | "maxDeltaTimeSeconds": 43200, 34 | "failureFactor": 30, 35 | "roles": { 36 | "realm": [ 37 | { 38 | "id": "cb157189-04a9-43e5-9951-c0223fb61518", 39 | "name": "uma_authorization", 40 | "description": "${role_uma_authorization}", 41 | "scopeParamRequired": false, 42 | "composite": false, 43 | "clientRole": false, 44 | "containerId": "realm_gem" 45 | }, 46 | { 47 | "id": "79fc649e-0d70-42f2-971c-52dda7c34b71", 48 | "name": "offline_access", 49 | "description": "${role_offline-access}", 50 | "scopeParamRequired": true, 51 | "composite": false, 52 | "clientRole": false, 53 | "containerId": "realm_gem" 54 | } 55 | ], 56 | "client": { 57 | "my_application": [ 58 | { 59 | "id": "014b8b41-bb6f-46d7-b439-3e1c9b947b6c", 60 | "name": "Public", 61 | "scopeParamRequired": false, 62 | "composite": false, 63 | "clientRole": true, 64 | "containerId": "95c392c2-d13a-4507-92a4-0771f40c3f9a" 65 | }, 66 | { 67 | "id": "712f4023-208b-45bc-991a-60871a3fa122", 68 | "name": "uma_protection", 69 | "scopeParamRequired": false, 70 | "composite": false, 71 | "clientRole": true, 72 | "containerId": "95c392c2-d13a-4507-92a4-0771f40c3f9a" 73 | } 74 | ], 75 | "realm-management": [ 76 | { 77 | "id": "0bd85d63-044f-4e73-af50-f4bc3f67f582", 78 | "name": "impersonation", 79 | "description": "${role_impersonation}", 80 | "scopeParamRequired": false, 81 | "composite": false, 82 | "clientRole": true, 83 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 84 | }, 85 | { 86 | "id": "a07890c4-b570-4eb2-ae1b-c554379f78dd", 87 | "name": "manage-identity-providers", 88 | "description": "${role_manage-identity-providers}", 89 | "scopeParamRequired": false, 90 | "composite": false, 91 | "clientRole": true, 92 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 93 | }, 94 | { 95 | "id": "f8d170fe-0986-4d49-9206-4c777fda0e4b", 96 | "name": "view-clients", 97 | "description": "${role_view-clients}", 98 | "scopeParamRequired": false, 99 | "composite": true, 100 | "composites": { 101 | "client": { 102 | "realm-management": [ 103 | "query-clients" 104 | ] 105 | } 106 | }, 107 | "clientRole": true, 108 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 109 | }, 110 | { 111 | "id": "d3b03e8d-4c22-4ca5-b114-120dcbf63592", 112 | "name": "query-clients", 113 | "description": "${role_query-clients}", 114 | "scopeParamRequired": false, 115 | "composite": false, 116 | "clientRole": true, 117 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 118 | }, 119 | { 120 | "id": "da5f9a9f-edff-46df-a2c8-20b7c1556992", 121 | "name": "manage-authorization", 122 | "description": "${role_manage-authorization}", 123 | "scopeParamRequired": false, 124 | "composite": false, 125 | "clientRole": true, 126 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 127 | }, 128 | { 129 | "id": "7fc36778-f189-4e3c-a1cd-399538a3e610", 130 | "name": "query-users", 131 | "description": "${role_query-users}", 132 | "scopeParamRequired": false, 133 | "composite": false, 134 | "clientRole": true, 135 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 136 | }, 137 | { 138 | "id": "ab95d8be-b067-443f-87a0-b018f585bdfd", 139 | "name": "query-realms", 140 | "description": "${role_query-realms}", 141 | "scopeParamRequired": false, 142 | "composite": false, 143 | "clientRole": true, 144 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 145 | }, 146 | { 147 | "id": "609ae30e-bd86-4fef-a39f-c3d7864708c1", 148 | "name": "create-client", 149 | "description": "${role_create-client}", 150 | "scopeParamRequired": false, 151 | "composite": false, 152 | "clientRole": true, 153 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 154 | }, 155 | { 156 | "id": "3d201d6f-5ac0-432d-b4ec-1c41c2ff2e58", 157 | "name": "manage-events", 158 | "description": "${role_manage-events}", 159 | "scopeParamRequired": false, 160 | "composite": false, 161 | "clientRole": true, 162 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 163 | }, 164 | { 165 | "id": "0c54c821-5bc1-4837-a94c-2c54dcb510fe", 166 | "name": "query-groups", 167 | "description": "${role_query-groups}", 168 | "scopeParamRequired": false, 169 | "composite": false, 170 | "clientRole": true, 171 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 172 | }, 173 | { 174 | "id": "c96253e8-1fa6-4ccd-b554-0d69af92cc3f", 175 | "name": "view-users", 176 | "description": "${role_view-users}", 177 | "scopeParamRequired": false, 178 | "composite": true, 179 | "composites": { 180 | "client": { 181 | "realm-management": [ 182 | "query-users", 183 | "query-groups" 184 | ] 185 | } 186 | }, 187 | "clientRole": true, 188 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 189 | }, 190 | { 191 | "id": "ec825e82-f10e-4616-9c06-80a74ded1271", 192 | "name": "view-identity-providers", 193 | "description": "${role_view-identity-providers}", 194 | "scopeParamRequired": false, 195 | "composite": false, 196 | "clientRole": true, 197 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 198 | }, 199 | { 200 | "id": "ff6e33bd-88a0-4bab-bfc6-24e14ed36ebf", 201 | "name": "view-realm", 202 | "description": "${role_view-realm}", 203 | "scopeParamRequired": false, 204 | "composite": false, 205 | "clientRole": true, 206 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 207 | }, 208 | { 209 | "id": "36114426-3ea7-4653-b391-16b57f11ea69", 210 | "name": "realm-admin", 211 | "description": "${role_realm-admin}", 212 | "scopeParamRequired": false, 213 | "composite": true, 214 | "composites": { 215 | "client": { 216 | "realm-management": [ 217 | "impersonation", 218 | "manage-identity-providers", 219 | "view-clients", 220 | "query-clients", 221 | "manage-authorization", 222 | "query-users", 223 | "query-realms", 224 | "manage-events", 225 | "create-client", 226 | "query-groups", 227 | "view-users", 228 | "view-identity-providers", 229 | "view-realm", 230 | "manage-users", 231 | "view-authorization", 232 | "view-events", 233 | "manage-realm", 234 | "manage-clients" 235 | ] 236 | } 237 | }, 238 | "clientRole": true, 239 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 240 | }, 241 | { 242 | "id": "9748cbef-d09c-4b64-bd8e-c2f750b740d4", 243 | "name": "view-authorization", 244 | "description": "${role_view-authorization}", 245 | "scopeParamRequired": false, 246 | "composite": false, 247 | "clientRole": true, 248 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 249 | }, 250 | { 251 | "id": "360ec0f6-5b06-4473-ab99-e76f62b28ece", 252 | "name": "manage-users", 253 | "description": "${role_manage-users}", 254 | "scopeParamRequired": false, 255 | "composite": false, 256 | "clientRole": true, 257 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 258 | }, 259 | { 260 | "id": "b07029c9-f186-4e24-83f4-8027890bab0e", 261 | "name": "view-events", 262 | "description": "${role_view-events}", 263 | "scopeParamRequired": false, 264 | "composite": false, 265 | "clientRole": true, 266 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 267 | }, 268 | { 269 | "id": "1984005b-b236-4228-a724-e1b9157dea32", 270 | "name": "manage-realm", 271 | "description": "${role_manage-realm}", 272 | "scopeParamRequired": false, 273 | "composite": false, 274 | "clientRole": true, 275 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 276 | }, 277 | { 278 | "id": "29e292c4-3845-41a0-87ce-accd529f2265", 279 | "name": "manage-clients", 280 | "description": "${role_manage-clients}", 281 | "scopeParamRequired": false, 282 | "composite": false, 283 | "clientRole": true, 284 | "containerId": "aca7cf4e-4291-4445-a746-71b2c1adf1a4" 285 | } 286 | ], 287 | "security-admin-console": [], 288 | "admin-cli": [], 289 | "broker": [ 290 | { 291 | "id": "757bdd59-ec8d-49ea-854e-fce8f063312b", 292 | "name": "read-token", 293 | "description": "${role_read-token}", 294 | "scopeParamRequired": false, 295 | "composite": false, 296 | "clientRole": true, 297 | "containerId": "6e68b046-8a4f-4e85-a725-c5a21a40096d" 298 | } 299 | ], 300 | "account": [ 301 | { 302 | "id": "9c4d9bc0-1e78-4bb3-ac61-b3ba8fddda42", 303 | "name": "manage-account", 304 | "description": "${role_manage-account}", 305 | "scopeParamRequired": false, 306 | "composite": true, 307 | "composites": { 308 | "client": { 309 | "account": [ 310 | "manage-account-links" 311 | ] 312 | } 313 | }, 314 | "clientRole": true, 315 | "containerId": "b9045b05-0586-4cd0-8166-da554819840b" 316 | }, 317 | { 318 | "id": "4d757a02-162d-48a8-9754-bf92cd1c0b14", 319 | "name": "manage-account-links", 320 | "description": "${role_manage-account-links}", 321 | "scopeParamRequired": false, 322 | "composite": false, 323 | "clientRole": true, 324 | "containerId": "b9045b05-0586-4cd0-8166-da554819840b" 325 | }, 326 | { 327 | "id": "9504b4c8-b40c-4898-9cad-7a863137f418", 328 | "name": "view-profile", 329 | "description": "${role_view-profile}", 330 | "scopeParamRequired": false, 331 | "composite": false, 332 | "clientRole": true, 333 | "containerId": "b9045b05-0586-4cd0-8166-da554819840b" 334 | } 335 | ] 336 | } 337 | }, 338 | "groups": [], 339 | "defaultRoles": [ 340 | "offline_access", 341 | "uma_authorization" 342 | ], 343 | "requiredCredentials": [ 344 | "password" 345 | ], 346 | "otpPolicyType": "totp", 347 | "otpPolicyAlgorithm": "HmacSHA1", 348 | "otpPolicyInitialCounter": 0, 349 | "otpPolicyDigits": 6, 350 | "otpPolicyLookAheadWindow": 1, 351 | "otpPolicyPeriod": 30, 352 | "otpSupportedApplications": [ 353 | "FreeOTP", 354 | "Google Authenticator" 355 | ], 356 | "clients": [ 357 | { 358 | "id": "0c523309-32de-4616-ba52-bccd3a10f545", 359 | "clientId": "admin-cli", 360 | "name": "${client_admin-cli}", 361 | "surrogateAuthRequired": false, 362 | "enabled": true, 363 | "clientAuthenticatorType": "client-secret", 364 | "secret": "**********", 365 | "redirectUris": [], 366 | "webOrigins": [], 367 | "notBefore": 0, 368 | "bearerOnly": false, 369 | "consentRequired": false, 370 | "standardFlowEnabled": false, 371 | "implicitFlowEnabled": false, 372 | "directAccessGrantsEnabled": true, 373 | "serviceAccountsEnabled": false, 374 | "publicClient": true, 375 | "frontchannelLogout": false, 376 | "protocol": "openid-connect", 377 | "attributes": {}, 378 | "fullScopeAllowed": false, 379 | "nodeReRegistrationTimeout": 0, 380 | "protocolMappers": [ 381 | { 382 | "id": "9cf2df68-2f14-4a5c-95bf-7e6c36dfef7e", 383 | "name": "role list", 384 | "protocol": "saml", 385 | "protocolMapper": "saml-role-list-mapper", 386 | "consentRequired": false, 387 | "config": { 388 | "single": "false", 389 | "attribute.nameformat": "Basic", 390 | "attribute.name": "Role" 391 | } 392 | }, 393 | { 394 | "id": "bd1f3c8c-3b47-4a53-8ca6-2e16f587006d", 395 | "name": "full name", 396 | "protocol": "openid-connect", 397 | "protocolMapper": "oidc-full-name-mapper", 398 | "consentRequired": true, 399 | "consentText": "${fullName}", 400 | "config": { 401 | "id.token.claim": "true", 402 | "access.token.claim": "true" 403 | } 404 | }, 405 | { 406 | "id": "ea988de1-a8bf-44a6-94c9-cc890abaf661", 407 | "name": "family name", 408 | "protocol": "openid-connect", 409 | "protocolMapper": "oidc-usermodel-property-mapper", 410 | "consentRequired": true, 411 | "consentText": "${familyName}", 412 | "config": { 413 | "userinfo.token.claim": "true", 414 | "user.attribute": "lastName", 415 | "id.token.claim": "true", 416 | "access.token.claim": "true", 417 | "claim.name": "family_name", 418 | "jsonType.label": "String" 419 | } 420 | }, 421 | { 422 | "id": "fe6bff4d-2f54-4435-8f95-d258dbe01eff", 423 | "name": "given name", 424 | "protocol": "openid-connect", 425 | "protocolMapper": "oidc-usermodel-property-mapper", 426 | "consentRequired": true, 427 | "consentText": "${givenName}", 428 | "config": { 429 | "userinfo.token.claim": "true", 430 | "user.attribute": "firstName", 431 | "id.token.claim": "true", 432 | "access.token.claim": "true", 433 | "claim.name": "given_name", 434 | "jsonType.label": "String" 435 | } 436 | }, 437 | { 438 | "id": "d059837f-e760-4d89-806c-87464b85cdaa", 439 | "name": "username", 440 | "protocol": "openid-connect", 441 | "protocolMapper": "oidc-usermodel-property-mapper", 442 | "consentRequired": true, 443 | "consentText": "${username}", 444 | "config": { 445 | "userinfo.token.claim": "true", 446 | "user.attribute": "username", 447 | "id.token.claim": "true", 448 | "access.token.claim": "true", 449 | "claim.name": "preferred_username", 450 | "jsonType.label": "String" 451 | } 452 | }, 453 | { 454 | "id": "111908cd-cda9-452d-88aa-f75495152879", 455 | "name": "email", 456 | "protocol": "openid-connect", 457 | "protocolMapper": "oidc-usermodel-property-mapper", 458 | "consentRequired": true, 459 | "consentText": "${email}", 460 | "config": { 461 | "userinfo.token.claim": "true", 462 | "user.attribute": "email", 463 | "id.token.claim": "true", 464 | "access.token.claim": "true", 465 | "claim.name": "email", 466 | "jsonType.label": "String" 467 | } 468 | } 469 | ], 470 | "useTemplateConfig": false, 471 | "useTemplateScope": false, 472 | "useTemplateMappers": false 473 | }, 474 | { 475 | "id": "6e68b046-8a4f-4e85-a725-c5a21a40096d", 476 | "clientId": "broker", 477 | "name": "${client_broker}", 478 | "surrogateAuthRequired": false, 479 | "enabled": true, 480 | "clientAuthenticatorType": "client-secret", 481 | "secret": "**********", 482 | "redirectUris": [], 483 | "webOrigins": [], 484 | "notBefore": 0, 485 | "bearerOnly": false, 486 | "consentRequired": false, 487 | "standardFlowEnabled": true, 488 | "implicitFlowEnabled": false, 489 | "directAccessGrantsEnabled": false, 490 | "serviceAccountsEnabled": false, 491 | "publicClient": false, 492 | "frontchannelLogout": false, 493 | "protocol": "openid-connect", 494 | "attributes": {}, 495 | "fullScopeAllowed": false, 496 | "nodeReRegistrationTimeout": 0, 497 | "protocolMappers": [ 498 | { 499 | "id": "200c8b2d-fdc2-43ec-9753-9fdb3f665860", 500 | "name": "role list", 501 | "protocol": "saml", 502 | "protocolMapper": "saml-role-list-mapper", 503 | "consentRequired": false, 504 | "config": { 505 | "single": "false", 506 | "attribute.nameformat": "Basic", 507 | "attribute.name": "Role" 508 | } 509 | }, 510 | { 511 | "id": "c7a9c083-47b6-49d2-bf18-26efe203276f", 512 | "name": "family name", 513 | "protocol": "openid-connect", 514 | "protocolMapper": "oidc-usermodel-property-mapper", 515 | "consentRequired": true, 516 | "consentText": "${familyName}", 517 | "config": { 518 | "userinfo.token.claim": "true", 519 | "user.attribute": "lastName", 520 | "id.token.claim": "true", 521 | "access.token.claim": "true", 522 | "claim.name": "family_name", 523 | "jsonType.label": "String" 524 | } 525 | }, 526 | { 527 | "id": "637a9c62-f912-4a2c-bc8e-2e5eba7b0d39", 528 | "name": "full name", 529 | "protocol": "openid-connect", 530 | "protocolMapper": "oidc-full-name-mapper", 531 | "consentRequired": true, 532 | "consentText": "${fullName}", 533 | "config": { 534 | "id.token.claim": "true", 535 | "access.token.claim": "true" 536 | } 537 | }, 538 | { 539 | "id": "c3a8a488-9b1f-47a7-92e7-bc718425f3ea", 540 | "name": "given name", 541 | "protocol": "openid-connect", 542 | "protocolMapper": "oidc-usermodel-property-mapper", 543 | "consentRequired": true, 544 | "consentText": "${givenName}", 545 | "config": { 546 | "userinfo.token.claim": "true", 547 | "user.attribute": "firstName", 548 | "id.token.claim": "true", 549 | "access.token.claim": "true", 550 | "claim.name": "given_name", 551 | "jsonType.label": "String" 552 | } 553 | }, 554 | { 555 | "id": "09c93966-8d14-4742-8755-411cc436a344", 556 | "name": "username", 557 | "protocol": "openid-connect", 558 | "protocolMapper": "oidc-usermodel-property-mapper", 559 | "consentRequired": true, 560 | "consentText": "${username}", 561 | "config": { 562 | "userinfo.token.claim": "true", 563 | "user.attribute": "username", 564 | "id.token.claim": "true", 565 | "access.token.claim": "true", 566 | "claim.name": "preferred_username", 567 | "jsonType.label": "String" 568 | } 569 | }, 570 | { 571 | "id": "16a8f425-9d61-4e80-aa56-af21d7e9729e", 572 | "name": "email", 573 | "protocol": "openid-connect", 574 | "protocolMapper": "oidc-usermodel-property-mapper", 575 | "consentRequired": true, 576 | "consentText": "${email}", 577 | "config": { 578 | "userinfo.token.claim": "true", 579 | "user.attribute": "email", 580 | "id.token.claim": "true", 581 | "access.token.claim": "true", 582 | "claim.name": "email", 583 | "jsonType.label": "String" 584 | } 585 | } 586 | ], 587 | "useTemplateConfig": false, 588 | "useTemplateScope": false, 589 | "useTemplateMappers": false 590 | }, 591 | { 592 | "id": "aca7cf4e-4291-4445-a746-71b2c1adf1a4", 593 | "clientId": "realm-management", 594 | "name": "${client_realm-management}", 595 | "surrogateAuthRequired": false, 596 | "enabled": true, 597 | "clientAuthenticatorType": "client-secret", 598 | "secret": "**********", 599 | "redirectUris": [], 600 | "webOrigins": [], 601 | "notBefore": 0, 602 | "bearerOnly": true, 603 | "consentRequired": false, 604 | "standardFlowEnabled": true, 605 | "implicitFlowEnabled": false, 606 | "directAccessGrantsEnabled": false, 607 | "serviceAccountsEnabled": false, 608 | "publicClient": false, 609 | "frontchannelLogout": false, 610 | "protocol": "openid-connect", 611 | "attributes": {}, 612 | "fullScopeAllowed": false, 613 | "nodeReRegistrationTimeout": 0, 614 | "protocolMappers": [ 615 | { 616 | "id": "41239965-9621-47ec-b1b6-864525a8ff2f", 617 | "name": "family name", 618 | "protocol": "openid-connect", 619 | "protocolMapper": "oidc-usermodel-property-mapper", 620 | "consentRequired": true, 621 | "consentText": "${familyName}", 622 | "config": { 623 | "userinfo.token.claim": "true", 624 | "user.attribute": "lastName", 625 | "id.token.claim": "true", 626 | "access.token.claim": "true", 627 | "claim.name": "family_name", 628 | "jsonType.label": "String" 629 | } 630 | }, 631 | { 632 | "id": "3dd42c7f-9ea0-437c-b6e0-5e5576405400", 633 | "name": "email", 634 | "protocol": "openid-connect", 635 | "protocolMapper": "oidc-usermodel-property-mapper", 636 | "consentRequired": true, 637 | "consentText": "${email}", 638 | "config": { 639 | "userinfo.token.claim": "true", 640 | "user.attribute": "email", 641 | "id.token.claim": "true", 642 | "access.token.claim": "true", 643 | "claim.name": "email", 644 | "jsonType.label": "String" 645 | } 646 | }, 647 | { 648 | "id": "4f19e6fc-bfc4-4673-8e6c-be75205d9552", 649 | "name": "full name", 650 | "protocol": "openid-connect", 651 | "protocolMapper": "oidc-full-name-mapper", 652 | "consentRequired": true, 653 | "consentText": "${fullName}", 654 | "config": { 655 | "id.token.claim": "true", 656 | "access.token.claim": "true" 657 | } 658 | }, 659 | { 660 | "id": "7efb1b8c-e783-48e9-b370-16546b251cdc", 661 | "name": "role list", 662 | "protocol": "saml", 663 | "protocolMapper": "saml-role-list-mapper", 664 | "consentRequired": false, 665 | "config": { 666 | "single": "false", 667 | "attribute.nameformat": "Basic", 668 | "attribute.name": "Role" 669 | } 670 | }, 671 | { 672 | "id": "adf21a74-2a0c-4b1d-8d11-efd9d2beb082", 673 | "name": "username", 674 | "protocol": "openid-connect", 675 | "protocolMapper": "oidc-usermodel-property-mapper", 676 | "consentRequired": true, 677 | "consentText": "${username}", 678 | "config": { 679 | "userinfo.token.claim": "true", 680 | "user.attribute": "username", 681 | "id.token.claim": "true", 682 | "access.token.claim": "true", 683 | "claim.name": "preferred_username", 684 | "jsonType.label": "String" 685 | } 686 | }, 687 | { 688 | "id": "59fa55c4-ba76-41ad-96c7-311aeb0d6114", 689 | "name": "given name", 690 | "protocol": "openid-connect", 691 | "protocolMapper": "oidc-usermodel-property-mapper", 692 | "consentRequired": true, 693 | "consentText": "${givenName}", 694 | "config": { 695 | "userinfo.token.claim": "true", 696 | "user.attribute": "firstName", 697 | "id.token.claim": "true", 698 | "access.token.claim": "true", 699 | "claim.name": "given_name", 700 | "jsonType.label": "String" 701 | } 702 | } 703 | ], 704 | "useTemplateConfig": false, 705 | "useTemplateScope": false, 706 | "useTemplateMappers": false 707 | }, 708 | { 709 | "id": "95c392c2-d13a-4507-92a4-0771f40c3f9a", 710 | "clientId": "my_application", 711 | "rootUrl": "localhost:3000", 712 | "adminUrl": "localhost:3000", 713 | "baseUrl": "localhost:3000", 714 | "surrogateAuthRequired": false, 715 | "enabled": true, 716 | "clientAuthenticatorType": "client-secret", 717 | "secret": "**********", 718 | "redirectUris": [ 719 | "localhost:3000/*", 720 | "*" 721 | ], 722 | "webOrigins": [ 723 | "localhost:3000" 724 | ], 725 | "notBefore": 0, 726 | "bearerOnly": false, 727 | "consentRequired": false, 728 | "standardFlowEnabled": true, 729 | "implicitFlowEnabled": false, 730 | "directAccessGrantsEnabled": true, 731 | "serviceAccountsEnabled": true, 732 | "authorizationServicesEnabled": true, 733 | "publicClient": false, 734 | "frontchannelLogout": false, 735 | "protocol": "openid-connect", 736 | "attributes": { 737 | "saml.assertion.signature": "false", 738 | "saml.force.post.binding": "false", 739 | "saml.multivalued.roles": "false", 740 | "saml.encrypt": "false", 741 | "saml_force_name_id_format": "false", 742 | "saml.client.signature": "false", 743 | "saml.authnstatement": "false", 744 | "saml.server.signature": "false", 745 | "saml.server.signature.keyinfo.ext": "false", 746 | "saml.onetimeuse.condition": "false" 747 | }, 748 | "fullScopeAllowed": true, 749 | "nodeReRegistrationTimeout": -1, 750 | "protocolMappers": [ 751 | { 752 | "id": "e173ece2-5ee4-4ef5-bd38-b55b0724784c", 753 | "name": "username", 754 | "protocol": "openid-connect", 755 | "protocolMapper": "oidc-usermodel-property-mapper", 756 | "consentRequired": true, 757 | "consentText": "${username}", 758 | "config": { 759 | "userinfo.token.claim": "true", 760 | "user.attribute": "username", 761 | "id.token.claim": "true", 762 | "access.token.claim": "true", 763 | "claim.name": "preferred_username", 764 | "jsonType.label": "String" 765 | } 766 | }, 767 | { 768 | "id": "1bc6a61e-1d61-48b9-9adc-52de375732f7", 769 | "name": "role list", 770 | "protocol": "saml", 771 | "protocolMapper": "saml-role-list-mapper", 772 | "consentRequired": false, 773 | "config": { 774 | "single": "false", 775 | "attribute.nameformat": "Basic", 776 | "attribute.name": "Role" 777 | } 778 | }, 779 | { 780 | "id": "bff10d19-c5d5-4bdd-875d-7b92bec7b773", 781 | "name": "email", 782 | "protocol": "openid-connect", 783 | "protocolMapper": "oidc-usermodel-property-mapper", 784 | "consentRequired": true, 785 | "consentText": "${email}", 786 | "config": { 787 | "userinfo.token.claim": "true", 788 | "user.attribute": "email", 789 | "id.token.claim": "true", 790 | "access.token.claim": "true", 791 | "claim.name": "email", 792 | "jsonType.label": "String" 793 | } 794 | }, 795 | { 796 | "id": "ba819f0d-5e44-402a-80e7-9ee9b1068c27", 797 | "name": "family name", 798 | "protocol": "openid-connect", 799 | "protocolMapper": "oidc-usermodel-property-mapper", 800 | "consentRequired": true, 801 | "consentText": "${familyName}", 802 | "config": { 803 | "userinfo.token.claim": "true", 804 | "user.attribute": "lastName", 805 | "id.token.claim": "true", 806 | "access.token.claim": "true", 807 | "claim.name": "family_name", 808 | "jsonType.label": "String" 809 | } 810 | }, 811 | { 812 | "id": "033c444a-d9ae-4fb7-8bc0-98ccddb794ff", 813 | "name": "full name", 814 | "protocol": "openid-connect", 815 | "protocolMapper": "oidc-full-name-mapper", 816 | "consentRequired": true, 817 | "consentText": "${fullName}", 818 | "config": { 819 | "id.token.claim": "true", 820 | "access.token.claim": "true" 821 | } 822 | }, 823 | { 824 | "id": "1902ab53-e416-4668-a9ae-56da2e747f55", 825 | "name": "Client Host", 826 | "protocol": "openid-connect", 827 | "protocolMapper": "oidc-usersessionmodel-note-mapper", 828 | "consentRequired": false, 829 | "consentText": "", 830 | "config": { 831 | "user.session.note": "clientHost", 832 | "id.token.claim": "true", 833 | "access.token.claim": "true", 834 | "claim.name": "clientHost", 835 | "jsonType.label": "String" 836 | } 837 | }, 838 | { 839 | "id": "ef0ee441-1d16-4393-a65a-fbaccfb8e2d9", 840 | "name": "given name", 841 | "protocol": "openid-connect", 842 | "protocolMapper": "oidc-usermodel-property-mapper", 843 | "consentRequired": true, 844 | "consentText": "${givenName}", 845 | "config": { 846 | "userinfo.token.claim": "true", 847 | "user.attribute": "firstName", 848 | "id.token.claim": "true", 849 | "access.token.claim": "true", 850 | "claim.name": "given_name", 851 | "jsonType.label": "String" 852 | } 853 | }, 854 | { 855 | "id": "6ea41b5f-0767-47a9-bd51-06ee78f867da", 856 | "name": "Client ID", 857 | "protocol": "openid-connect", 858 | "protocolMapper": "oidc-usersessionmodel-note-mapper", 859 | "consentRequired": false, 860 | "consentText": "", 861 | "config": { 862 | "user.session.note": "clientId", 863 | "id.token.claim": "true", 864 | "access.token.claim": "true", 865 | "claim.name": "clientId", 866 | "jsonType.label": "String" 867 | } 868 | }, 869 | { 870 | "id": "7b07763a-2266-4f3c-b6a2-005d20a83aea", 871 | "name": "Client IP Address", 872 | "protocol": "openid-connect", 873 | "protocolMapper": "oidc-usersessionmodel-note-mapper", 874 | "consentRequired": false, 875 | "consentText": "", 876 | "config": { 877 | "user.session.note": "clientAddress", 878 | "id.token.claim": "true", 879 | "access.token.claim": "true", 880 | "claim.name": "clientAddress", 881 | "jsonType.label": "String" 882 | } 883 | } 884 | ], 885 | "useTemplateConfig": false, 886 | "useTemplateScope": false, 887 | "useTemplateMappers": false, 888 | "authorizationSettings": { 889 | "allowRemoteResourceManagement": false, 890 | "policyEnforcementMode": "ENFORCING", 891 | "resources": [ 892 | { 893 | "name": "Default Resource", 894 | "uri": "/*", 895 | "type": "urn:my_application:resources:default" 896 | } 897 | ], 898 | "policies": [ 899 | { 900 | "name": "Default Policy", 901 | "description": "A policy that grants access only for users within this realm", 902 | "type": "js", 903 | "logic": "POSITIVE", 904 | "decisionStrategy": "AFFIRMATIVE", 905 | "config": { 906 | "code": "// by default, grants any permission associated with this policy\n$evaluation.grant();\n" 907 | } 908 | }, 909 | { 910 | "name": "Default Permission", 911 | "description": "A permission that applies to the default resource type", 912 | "type": "resource", 913 | "logic": "POSITIVE", 914 | "decisionStrategy": "UNANIMOUS", 915 | "config": { 916 | "defaultResourceType": "urn:my_application:resources:default", 917 | "applyPolicies": "[\"Default Policy\"]" 918 | } 919 | } 920 | ], 921 | "scopes": [] 922 | } 923 | }, 924 | { 925 | "id": "b9045b05-0586-4cd0-8166-da554819840b", 926 | "clientId": "account", 927 | "name": "${client_account}", 928 | "baseUrl": "/auth/realms/realm_gem/account", 929 | "surrogateAuthRequired": false, 930 | "enabled": true, 931 | "clientAuthenticatorType": "client-secret", 932 | "secret": "**********", 933 | "defaultRoles": [ 934 | "view-profile", 935 | "manage-account" 936 | ], 937 | "redirectUris": [ 938 | "/auth/realms/realm_gem/account/*" 939 | ], 940 | "webOrigins": [], 941 | "notBefore": 0, 942 | "bearerOnly": false, 943 | "consentRequired": false, 944 | "standardFlowEnabled": true, 945 | "implicitFlowEnabled": false, 946 | "directAccessGrantsEnabled": false, 947 | "serviceAccountsEnabled": false, 948 | "publicClient": false, 949 | "frontchannelLogout": false, 950 | "protocol": "openid-connect", 951 | "attributes": {}, 952 | "fullScopeAllowed": false, 953 | "nodeReRegistrationTimeout": 0, 954 | "protocolMappers": [ 955 | { 956 | "id": "54dbed07-bb33-429a-b347-7c2a3a5976cb", 957 | "name": "username", 958 | "protocol": "openid-connect", 959 | "protocolMapper": "oidc-usermodel-property-mapper", 960 | "consentRequired": true, 961 | "consentText": "${username}", 962 | "config": { 963 | "userinfo.token.claim": "true", 964 | "user.attribute": "username", 965 | "id.token.claim": "true", 966 | "access.token.claim": "true", 967 | "claim.name": "preferred_username", 968 | "jsonType.label": "String" 969 | } 970 | }, 971 | { 972 | "id": "2d4282d2-9fdf-426f-806f-f1914c5569f9", 973 | "name": "family name", 974 | "protocol": "openid-connect", 975 | "protocolMapper": "oidc-usermodel-property-mapper", 976 | "consentRequired": true, 977 | "consentText": "${familyName}", 978 | "config": { 979 | "userinfo.token.claim": "true", 980 | "user.attribute": "lastName", 981 | "id.token.claim": "true", 982 | "access.token.claim": "true", 983 | "claim.name": "family_name", 984 | "jsonType.label": "String" 985 | } 986 | }, 987 | { 988 | "id": "33f4fe0e-e59d-4e58-a20f-73e0fff8412d", 989 | "name": "given name", 990 | "protocol": "openid-connect", 991 | "protocolMapper": "oidc-usermodel-property-mapper", 992 | "consentRequired": true, 993 | "consentText": "${givenName}", 994 | "config": { 995 | "userinfo.token.claim": "true", 996 | "user.attribute": "firstName", 997 | "id.token.claim": "true", 998 | "access.token.claim": "true", 999 | "claim.name": "given_name", 1000 | "jsonType.label": "String" 1001 | } 1002 | }, 1003 | { 1004 | "id": "ca9b96a6-60c3-41b2-8278-5c1958755250", 1005 | "name": "email", 1006 | "protocol": "openid-connect", 1007 | "protocolMapper": "oidc-usermodel-property-mapper", 1008 | "consentRequired": true, 1009 | "consentText": "${email}", 1010 | "config": { 1011 | "userinfo.token.claim": "true", 1012 | "user.attribute": "email", 1013 | "id.token.claim": "true", 1014 | "access.token.claim": "true", 1015 | "claim.name": "email", 1016 | "jsonType.label": "String" 1017 | } 1018 | }, 1019 | { 1020 | "id": "f28452f8-ca25-47ee-b3f1-81490d1fd51f", 1021 | "name": "full name", 1022 | "protocol": "openid-connect", 1023 | "protocolMapper": "oidc-full-name-mapper", 1024 | "consentRequired": true, 1025 | "consentText": "${fullName}", 1026 | "config": { 1027 | "id.token.claim": "true", 1028 | "access.token.claim": "true" 1029 | } 1030 | }, 1031 | { 1032 | "id": "ed693d52-ee29-45d6-bd02-b2ec05c351d0", 1033 | "name": "role list", 1034 | "protocol": "saml", 1035 | "protocolMapper": "saml-role-list-mapper", 1036 | "consentRequired": false, 1037 | "config": { 1038 | "single": "false", 1039 | "attribute.nameformat": "Basic", 1040 | "attribute.name": "Role" 1041 | } 1042 | } 1043 | ], 1044 | "useTemplateConfig": false, 1045 | "useTemplateScope": false, 1046 | "useTemplateMappers": false 1047 | }, 1048 | { 1049 | "id": "4bea0e80-487d-49e4-919f-93e468196dac", 1050 | "clientId": "security-admin-console", 1051 | "name": "${client_security-admin-console}", 1052 | "baseUrl": "/auth/admin/realm_gem/console/index.html", 1053 | "surrogateAuthRequired": false, 1054 | "enabled": true, 1055 | "clientAuthenticatorType": "client-secret", 1056 | "secret": "**********", 1057 | "redirectUris": [ 1058 | "/auth/admin/realm_gem/console/*" 1059 | ], 1060 | "webOrigins": [], 1061 | "notBefore": 0, 1062 | "bearerOnly": false, 1063 | "consentRequired": false, 1064 | "standardFlowEnabled": true, 1065 | "implicitFlowEnabled": false, 1066 | "directAccessGrantsEnabled": false, 1067 | "serviceAccountsEnabled": false, 1068 | "publicClient": true, 1069 | "frontchannelLogout": false, 1070 | "protocol": "openid-connect", 1071 | "attributes": {}, 1072 | "fullScopeAllowed": false, 1073 | "nodeReRegistrationTimeout": 0, 1074 | "protocolMappers": [ 1075 | { 1076 | "id": "088e556d-ecbc-4513-ba0a-1d7750ff4097", 1077 | "name": "locale", 1078 | "protocol": "openid-connect", 1079 | "protocolMapper": "oidc-usermodel-attribute-mapper", 1080 | "consentRequired": false, 1081 | "consentText": "${locale}", 1082 | "config": { 1083 | "userinfo.token.claim": "true", 1084 | "user.attribute": "locale", 1085 | "id.token.claim": "true", 1086 | "access.token.claim": "true", 1087 | "claim.name": "locale", 1088 | "jsonType.label": "String" 1089 | } 1090 | }, 1091 | { 1092 | "id": "52809f6d-cbd5-46b5-acbc-9f0a4d1ea99f", 1093 | "name": "username", 1094 | "protocol": "openid-connect", 1095 | "protocolMapper": "oidc-usermodel-property-mapper", 1096 | "consentRequired": true, 1097 | "consentText": "${username}", 1098 | "config": { 1099 | "userinfo.token.claim": "true", 1100 | "user.attribute": "username", 1101 | "id.token.claim": "true", 1102 | "access.token.claim": "true", 1103 | "claim.name": "preferred_username", 1104 | "jsonType.label": "String" 1105 | } 1106 | }, 1107 | { 1108 | "id": "bf666334-d4a5-4be6-ade4-1dea460c9863", 1109 | "name": "role list", 1110 | "protocol": "saml", 1111 | "protocolMapper": "saml-role-list-mapper", 1112 | "consentRequired": false, 1113 | "config": { 1114 | "single": "false", 1115 | "attribute.nameformat": "Basic", 1116 | "attribute.name": "Role" 1117 | } 1118 | }, 1119 | { 1120 | "id": "1b16cc71-a3d8-4c5b-b3da-f31cee37cf93", 1121 | "name": "email", 1122 | "protocol": "openid-connect", 1123 | "protocolMapper": "oidc-usermodel-property-mapper", 1124 | "consentRequired": true, 1125 | "consentText": "${email}", 1126 | "config": { 1127 | "userinfo.token.claim": "true", 1128 | "user.attribute": "email", 1129 | "id.token.claim": "true", 1130 | "access.token.claim": "true", 1131 | "claim.name": "email", 1132 | "jsonType.label": "String" 1133 | } 1134 | }, 1135 | { 1136 | "id": "78b94941-ed89-4423-b9c1-82fb93835289", 1137 | "name": "full name", 1138 | "protocol": "openid-connect", 1139 | "protocolMapper": "oidc-full-name-mapper", 1140 | "consentRequired": true, 1141 | "consentText": "${fullName}", 1142 | "config": { 1143 | "id.token.claim": "true", 1144 | "access.token.claim": "true" 1145 | } 1146 | }, 1147 | { 1148 | "id": "bdc5acfd-bd6d-42fb-9d8d-573ab80ef238", 1149 | "name": "family name", 1150 | "protocol": "openid-connect", 1151 | "protocolMapper": "oidc-usermodel-property-mapper", 1152 | "consentRequired": true, 1153 | "consentText": "${familyName}", 1154 | "config": { 1155 | "userinfo.token.claim": "true", 1156 | "user.attribute": "lastName", 1157 | "id.token.claim": "true", 1158 | "access.token.claim": "true", 1159 | "claim.name": "family_name", 1160 | "jsonType.label": "String" 1161 | } 1162 | }, 1163 | { 1164 | "id": "ab75e815-168e-4e95-bea4-5a770dc06684", 1165 | "name": "given name", 1166 | "protocol": "openid-connect", 1167 | "protocolMapper": "oidc-usermodel-property-mapper", 1168 | "consentRequired": true, 1169 | "consentText": "${givenName}", 1170 | "config": { 1171 | "userinfo.token.claim": "true", 1172 | "user.attribute": "firstName", 1173 | "id.token.claim": "true", 1174 | "access.token.claim": "true", 1175 | "claim.name": "given_name", 1176 | "jsonType.label": "String" 1177 | } 1178 | } 1179 | ], 1180 | "useTemplateConfig": false, 1181 | "useTemplateScope": false, 1182 | "useTemplateMappers": false 1183 | } 1184 | ], 1185 | "clientTemplates": [], 1186 | "browserSecurityHeaders": { 1187 | "xContentTypeOptions": "nosniff", 1188 | "xRobotsTag": "none", 1189 | "xFrameOptions": "SAMEORIGIN", 1190 | "xXSSProtection": "1; mode=block", 1191 | "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", 1192 | "strictTransportSecurity": "max-age=31536000; includeSubDomains" 1193 | }, 1194 | "smtpServer": { 1195 | "password": "**********", 1196 | "starttls": "true", 1197 | "auth": "true", 1198 | "port": "587", 1199 | "host": "smtp.campinas.sp.gov.br", 1200 | "from": "naoresponder@campinas.sp.gov.br", 1201 | "fromDisplayName": "Campinas", 1202 | "ssl": "", 1203 | "user": "naoresponder@campinas.sp.gov.br" 1204 | }, 1205 | "eventsEnabled": false, 1206 | "eventsListeners": [ 1207 | "jboss-logging" 1208 | ], 1209 | "enabledEventTypes": [], 1210 | "adminEventsEnabled": false, 1211 | "adminEventsDetailsEnabled": false, 1212 | "components": { 1213 | "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ 1214 | { 1215 | "id": "48971dab-4739-4295-aa61-1e9dbd1877ab", 1216 | "name": "Consent Required", 1217 | "providerId": "consent-required", 1218 | "subType": "anonymous", 1219 | "subComponents": {}, 1220 | "config": {} 1221 | }, 1222 | { 1223 | "id": "c7d6b5ed-3b90-43c4-b150-6159409f1d77", 1224 | "name": "Allowed Protocol Mapper Types", 1225 | "providerId": "allowed-protocol-mappers", 1226 | "subType": "anonymous", 1227 | "subComponents": {}, 1228 | "config": { 1229 | "allowed-protocol-mapper-types": [ 1230 | "oidc-sha256-pairwise-sub-mapper", 1231 | "oidc-address-mapper", 1232 | "saml-role-list-mapper", 1233 | "saml-user-property-mapper", 1234 | "saml-user-attribute-mapper", 1235 | "oidc-usermodel-attribute-mapper", 1236 | "oidc-full-name-mapper", 1237 | "oidc-usermodel-property-mapper" 1238 | ], 1239 | "consent-required-for-all-mappers": [ 1240 | "true" 1241 | ] 1242 | } 1243 | }, 1244 | { 1245 | "id": "25575481-ae9c-4faa-a67d-b364de04a69e", 1246 | "name": "Allowed Client Templates", 1247 | "providerId": "allowed-client-templates", 1248 | "subType": "authenticated", 1249 | "subComponents": {}, 1250 | "config": {} 1251 | }, 1252 | { 1253 | "id": "242f6bc1-54f3-4864-a595-725649e1579f", 1254 | "name": "Allowed Protocol Mapper Types", 1255 | "providerId": "allowed-protocol-mappers", 1256 | "subType": "authenticated", 1257 | "subComponents": {}, 1258 | "config": { 1259 | "allowed-protocol-mapper-types": [ 1260 | "oidc-usermodel-attribute-mapper", 1261 | "oidc-usermodel-property-mapper", 1262 | "saml-user-attribute-mapper", 1263 | "oidc-address-mapper", 1264 | "oidc-full-name-mapper", 1265 | "saml-role-list-mapper", 1266 | "oidc-sha256-pairwise-sub-mapper", 1267 | "saml-user-property-mapper" 1268 | ], 1269 | "consent-required-for-all-mappers": [ 1270 | "true" 1271 | ] 1272 | } 1273 | }, 1274 | { 1275 | "id": "131746c0-d98d-4db8-abc1-ab9b51a1dfc7", 1276 | "name": "Trusted Hosts", 1277 | "providerId": "trusted-hosts", 1278 | "subType": "anonymous", 1279 | "subComponents": {}, 1280 | "config": { 1281 | "host-sending-registration-request-must-match": [ 1282 | "true" 1283 | ], 1284 | "client-uris-must-match": [ 1285 | "true" 1286 | ] 1287 | } 1288 | }, 1289 | { 1290 | "id": "ff09f6dd-a499-4679-b617-197eb9681315", 1291 | "name": "Max Clients Limit", 1292 | "providerId": "max-clients", 1293 | "subType": "anonymous", 1294 | "subComponents": {}, 1295 | "config": { 1296 | "max-clients": [ 1297 | "200" 1298 | ] 1299 | } 1300 | }, 1301 | { 1302 | "id": "c7fe5588-5207-460d-8829-1f4eea9f6265", 1303 | "name": "Allowed Client Templates", 1304 | "providerId": "allowed-client-templates", 1305 | "subType": "anonymous", 1306 | "subComponents": {}, 1307 | "config": {} 1308 | }, 1309 | { 1310 | "id": "92d316a8-46ee-485c-92ca-006ff6a88368", 1311 | "name": "Full Scope Disabled", 1312 | "providerId": "scope", 1313 | "subType": "anonymous", 1314 | "subComponents": {}, 1315 | "config": {} 1316 | } 1317 | ], 1318 | "org.keycloak.keys.KeyProvider": [ 1319 | { 1320 | "id": "c7acf36b-f1ae-43c5-aad7-33bda694b12d", 1321 | "name": "hmac-generated", 1322 | "providerId": "hmac-generated", 1323 | "subComponents": {}, 1324 | "config": { 1325 | "priority": [ 1326 | "100" 1327 | ] 1328 | } 1329 | }, 1330 | { 1331 | "id": "b104e033-48c3-481b-b9e1-778a23dd232b", 1332 | "name": "aes-generated", 1333 | "providerId": "aes-generated", 1334 | "subComponents": {}, 1335 | "config": { 1336 | "priority": [ 1337 | "100" 1338 | ] 1339 | } 1340 | }, 1341 | { 1342 | "id": "094ec913-bbc0-41e5-a416-cdaa07e4f148", 1343 | "name": "rsa-generated", 1344 | "providerId": "rsa-generated", 1345 | "subComponents": {}, 1346 | "config": { 1347 | "priority": [ 1348 | "100" 1349 | ] 1350 | } 1351 | } 1352 | ] 1353 | }, 1354 | "internationalizationEnabled": false, 1355 | "supportedLocales": [], 1356 | "authenticationFlows": [ 1357 | { 1358 | "id": "2bef4caa-18bc-42fe-b11f-fbe57bd90cd7", 1359 | "alias": "Handle Existing Account", 1360 | "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", 1361 | "providerId": "basic-flow", 1362 | "topLevel": false, 1363 | "builtIn": true, 1364 | "authenticationExecutions": [ 1365 | { 1366 | "authenticator": "idp-confirm-link", 1367 | "requirement": "REQUIRED", 1368 | "priority": 10, 1369 | "userSetupAllowed": false, 1370 | "autheticatorFlow": false 1371 | }, 1372 | { 1373 | "authenticator": "idp-email-verification", 1374 | "requirement": "ALTERNATIVE", 1375 | "priority": 20, 1376 | "userSetupAllowed": false, 1377 | "autheticatorFlow": false 1378 | }, 1379 | { 1380 | "requirement": "ALTERNATIVE", 1381 | "priority": 30, 1382 | "flowAlias": "Verify Existing Account by Re-authentication", 1383 | "userSetupAllowed": false, 1384 | "autheticatorFlow": true 1385 | } 1386 | ] 1387 | }, 1388 | { 1389 | "id": "258ef9ec-f8d3-43dd-9e5e-93dbf9b17f2d", 1390 | "alias": "Verify Existing Account by Re-authentication", 1391 | "description": "Reauthentication of existing account", 1392 | "providerId": "basic-flow", 1393 | "topLevel": false, 1394 | "builtIn": true, 1395 | "authenticationExecutions": [ 1396 | { 1397 | "authenticator": "idp-username-password-form", 1398 | "requirement": "REQUIRED", 1399 | "priority": 10, 1400 | "userSetupAllowed": false, 1401 | "autheticatorFlow": false 1402 | }, 1403 | { 1404 | "authenticator": "auth-otp-form", 1405 | "requirement": "OPTIONAL", 1406 | "priority": 20, 1407 | "userSetupAllowed": false, 1408 | "autheticatorFlow": false 1409 | } 1410 | ] 1411 | }, 1412 | { 1413 | "id": "8bcb2d69-6596-4e29-a954-7d9e721f8bd5", 1414 | "alias": "browser", 1415 | "description": "browser based authentication", 1416 | "providerId": "basic-flow", 1417 | "topLevel": true, 1418 | "builtIn": true, 1419 | "authenticationExecutions": [ 1420 | { 1421 | "authenticator": "auth-cookie", 1422 | "requirement": "ALTERNATIVE", 1423 | "priority": 10, 1424 | "userSetupAllowed": false, 1425 | "autheticatorFlow": false 1426 | }, 1427 | { 1428 | "authenticator": "auth-spnego", 1429 | "requirement": "DISABLED", 1430 | "priority": 20, 1431 | "userSetupAllowed": false, 1432 | "autheticatorFlow": false 1433 | }, 1434 | { 1435 | "authenticator": "identity-provider-redirector", 1436 | "requirement": "ALTERNATIVE", 1437 | "priority": 25, 1438 | "userSetupAllowed": false, 1439 | "autheticatorFlow": false 1440 | }, 1441 | { 1442 | "requirement": "ALTERNATIVE", 1443 | "priority": 30, 1444 | "flowAlias": "forms", 1445 | "userSetupAllowed": false, 1446 | "autheticatorFlow": true 1447 | } 1448 | ] 1449 | }, 1450 | { 1451 | "id": "b7c39ef3-cbb1-48f4-be77-2fb06bcc73b6", 1452 | "alias": "clients", 1453 | "description": "Base authentication for clients", 1454 | "providerId": "client-flow", 1455 | "topLevel": true, 1456 | "builtIn": true, 1457 | "authenticationExecutions": [ 1458 | { 1459 | "authenticator": "client-secret", 1460 | "requirement": "ALTERNATIVE", 1461 | "priority": 10, 1462 | "userSetupAllowed": false, 1463 | "autheticatorFlow": false 1464 | }, 1465 | { 1466 | "authenticator": "client-jwt", 1467 | "requirement": "ALTERNATIVE", 1468 | "priority": 20, 1469 | "userSetupAllowed": false, 1470 | "autheticatorFlow": false 1471 | } 1472 | ] 1473 | }, 1474 | { 1475 | "id": "114993cf-b80a-4377-b4eb-d88c2ef83949", 1476 | "alias": "direct grant", 1477 | "description": "OpenID Connect Resource Owner Grant", 1478 | "providerId": "basic-flow", 1479 | "topLevel": true, 1480 | "builtIn": true, 1481 | "authenticationExecutions": [ 1482 | { 1483 | "authenticator": "direct-grant-validate-username", 1484 | "requirement": "REQUIRED", 1485 | "priority": 10, 1486 | "userSetupAllowed": false, 1487 | "autheticatorFlow": false 1488 | }, 1489 | { 1490 | "authenticator": "direct-grant-validate-password", 1491 | "requirement": "REQUIRED", 1492 | "priority": 20, 1493 | "userSetupAllowed": false, 1494 | "autheticatorFlow": false 1495 | }, 1496 | { 1497 | "authenticator": "direct-grant-validate-otp", 1498 | "requirement": "OPTIONAL", 1499 | "priority": 30, 1500 | "userSetupAllowed": false, 1501 | "autheticatorFlow": false 1502 | } 1503 | ] 1504 | }, 1505 | { 1506 | "id": "3ab6b2bc-507b-40e9-a590-72cc5ab62b06", 1507 | "alias": "docker auth", 1508 | "description": "Used by Docker clients to authenticate against the IDP", 1509 | "providerId": "basic-flow", 1510 | "topLevel": true, 1511 | "builtIn": true, 1512 | "authenticationExecutions": [ 1513 | { 1514 | "authenticator": "docker-http-basic-authenticator", 1515 | "requirement": "REQUIRED", 1516 | "priority": 10, 1517 | "userSetupAllowed": false, 1518 | "autheticatorFlow": false 1519 | } 1520 | ] 1521 | }, 1522 | { 1523 | "id": "bcc51a7d-1ed0-4962-a830-830e72008d0d", 1524 | "alias": "first broker login", 1525 | "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", 1526 | "providerId": "basic-flow", 1527 | "topLevel": true, 1528 | "builtIn": true, 1529 | "authenticationExecutions": [ 1530 | { 1531 | "authenticatorConfig": "review profile config", 1532 | "authenticator": "idp-review-profile", 1533 | "requirement": "REQUIRED", 1534 | "priority": 10, 1535 | "userSetupAllowed": false, 1536 | "autheticatorFlow": false 1537 | }, 1538 | { 1539 | "authenticatorConfig": "create unique user config", 1540 | "authenticator": "idp-create-user-if-unique", 1541 | "requirement": "ALTERNATIVE", 1542 | "priority": 20, 1543 | "userSetupAllowed": false, 1544 | "autheticatorFlow": false 1545 | }, 1546 | { 1547 | "requirement": "ALTERNATIVE", 1548 | "priority": 30, 1549 | "flowAlias": "Handle Existing Account", 1550 | "userSetupAllowed": false, 1551 | "autheticatorFlow": true 1552 | } 1553 | ] 1554 | }, 1555 | { 1556 | "id": "6799eca7-6a9d-47d5-b44e-3a6625fb2cef", 1557 | "alias": "forms", 1558 | "description": "Username, password, otp and other auth forms.", 1559 | "providerId": "basic-flow", 1560 | "topLevel": false, 1561 | "builtIn": true, 1562 | "authenticationExecutions": [ 1563 | { 1564 | "authenticator": "auth-username-password-form", 1565 | "requirement": "REQUIRED", 1566 | "priority": 10, 1567 | "userSetupAllowed": false, 1568 | "autheticatorFlow": false 1569 | }, 1570 | { 1571 | "authenticator": "auth-otp-form", 1572 | "requirement": "OPTIONAL", 1573 | "priority": 20, 1574 | "userSetupAllowed": false, 1575 | "autheticatorFlow": false 1576 | } 1577 | ] 1578 | }, 1579 | { 1580 | "id": "27bc0ee8-a0b5-4239-b194-fb62f663e227", 1581 | "alias": "registration", 1582 | "description": "registration flow", 1583 | "providerId": "basic-flow", 1584 | "topLevel": true, 1585 | "builtIn": true, 1586 | "authenticationExecutions": [ 1587 | { 1588 | "authenticator": "registration-page-form", 1589 | "requirement": "REQUIRED", 1590 | "priority": 10, 1591 | "flowAlias": "registration form", 1592 | "userSetupAllowed": false, 1593 | "autheticatorFlow": true 1594 | } 1595 | ] 1596 | }, 1597 | { 1598 | "id": "7a965f5b-df71-4a47-b153-4afc3d54f045", 1599 | "alias": "registration form", 1600 | "description": "registration form", 1601 | "providerId": "form-flow", 1602 | "topLevel": false, 1603 | "builtIn": true, 1604 | "authenticationExecutions": [ 1605 | { 1606 | "authenticator": "registration-user-creation", 1607 | "requirement": "REQUIRED", 1608 | "priority": 20, 1609 | "userSetupAllowed": false, 1610 | "autheticatorFlow": false 1611 | }, 1612 | { 1613 | "authenticator": "registration-profile-action", 1614 | "requirement": "REQUIRED", 1615 | "priority": 40, 1616 | "userSetupAllowed": false, 1617 | "autheticatorFlow": false 1618 | }, 1619 | { 1620 | "authenticator": "registration-password-action", 1621 | "requirement": "REQUIRED", 1622 | "priority": 50, 1623 | "userSetupAllowed": false, 1624 | "autheticatorFlow": false 1625 | }, 1626 | { 1627 | "authenticator": "registration-recaptcha-action", 1628 | "requirement": "DISABLED", 1629 | "priority": 60, 1630 | "userSetupAllowed": false, 1631 | "autheticatorFlow": false 1632 | } 1633 | ] 1634 | }, 1635 | { 1636 | "id": "17586847-c09c-4884-b6c5-53a068c81831", 1637 | "alias": "reset credentials", 1638 | "description": "Reset credentials for a user if they forgot their password or something", 1639 | "providerId": "basic-flow", 1640 | "topLevel": true, 1641 | "builtIn": true, 1642 | "authenticationExecutions": [ 1643 | { 1644 | "authenticator": "reset-credentials-choose-user", 1645 | "requirement": "REQUIRED", 1646 | "priority": 10, 1647 | "userSetupAllowed": false, 1648 | "autheticatorFlow": false 1649 | }, 1650 | { 1651 | "authenticator": "reset-credential-email", 1652 | "requirement": "REQUIRED", 1653 | "priority": 20, 1654 | "userSetupAllowed": false, 1655 | "autheticatorFlow": false 1656 | }, 1657 | { 1658 | "authenticator": "reset-password", 1659 | "requirement": "REQUIRED", 1660 | "priority": 30, 1661 | "userSetupAllowed": false, 1662 | "autheticatorFlow": false 1663 | }, 1664 | { 1665 | "authenticator": "reset-otp", 1666 | "requirement": "OPTIONAL", 1667 | "priority": 40, 1668 | "userSetupAllowed": false, 1669 | "autheticatorFlow": false 1670 | } 1671 | ] 1672 | }, 1673 | { 1674 | "id": "331828b1-4421-42b9-b0f1-74fd93820fa1", 1675 | "alias": "saml ecp", 1676 | "description": "SAML ECP Profile Authentication Flow", 1677 | "providerId": "basic-flow", 1678 | "topLevel": true, 1679 | "builtIn": true, 1680 | "authenticationExecutions": [ 1681 | { 1682 | "authenticator": "http-basic-authenticator", 1683 | "requirement": "REQUIRED", 1684 | "priority": 10, 1685 | "userSetupAllowed": false, 1686 | "autheticatorFlow": false 1687 | } 1688 | ] 1689 | } 1690 | ], 1691 | "authenticatorConfig": [ 1692 | { 1693 | "id": "4603d77b-443a-4f3a-8511-dd97a2c112e9", 1694 | "alias": "create unique user config", 1695 | "config": { 1696 | "require.password.update.after.registration": "false" 1697 | } 1698 | }, 1699 | { 1700 | "id": "4828301b-630d-43b7-8b6f-6fadcecf8cdb", 1701 | "alias": "review profile config", 1702 | "config": { 1703 | "update.profile.on.first.login": "missing" 1704 | } 1705 | } 1706 | ], 1707 | "requiredActions": [ 1708 | { 1709 | "alias": "CONFIGURE_TOTP", 1710 | "name": "Configure OTP", 1711 | "providerId": "CONFIGURE_TOTP", 1712 | "enabled": true, 1713 | "defaultAction": false, 1714 | "config": {} 1715 | }, 1716 | { 1717 | "alias": "UPDATE_PASSWORD", 1718 | "name": "Update Password", 1719 | "providerId": "UPDATE_PASSWORD", 1720 | "enabled": true, 1721 | "defaultAction": false, 1722 | "config": {} 1723 | }, 1724 | { 1725 | "alias": "UPDATE_PROFILE", 1726 | "name": "Update Profile", 1727 | "providerId": "UPDATE_PROFILE", 1728 | "enabled": true, 1729 | "defaultAction": false, 1730 | "config": {} 1731 | }, 1732 | { 1733 | "alias": "VERIFY_EMAIL", 1734 | "name": "Verify Email", 1735 | "providerId": "VERIFY_EMAIL", 1736 | "enabled": true, 1737 | "defaultAction": false, 1738 | "config": {} 1739 | }, 1740 | { 1741 | "alias": "terms_and_conditions", 1742 | "name": "Terms and Conditions", 1743 | "providerId": "terms_and_conditions", 1744 | "enabled": false, 1745 | "defaultAction": false, 1746 | "config": {} 1747 | } 1748 | ], 1749 | "browserFlow": "browser", 1750 | "registrationFlow": "registration", 1751 | "directGrantFlow": "direct grant", 1752 | "resetCredentialsFlow": "reset credentials", 1753 | "clientAuthenticationFlow": "clients", 1754 | "dockerAuthenticationFlow": "docker auth", 1755 | "attributes": { 1756 | "_browser_header.xXSSProtection": "1; mode=block", 1757 | "_browser_header.xFrameOptions": "SAMEORIGIN", 1758 | "_browser_header.strictTransportSecurity": "max-age=31536000; includeSubDomains", 1759 | "permanentLockout": "false", 1760 | "quickLoginCheckMilliSeconds": "1000", 1761 | "_browser_header.xRobotsTag": "none", 1762 | "maxFailureWaitSeconds": "900", 1763 | "minimumQuickLoginWaitSeconds": "60", 1764 | "failureFactor": "30", 1765 | "actionTokenGeneratedByUserLifespan": "300", 1766 | "maxDeltaTimeSeconds": "43200", 1767 | "_browser_header.xContentTypeOptions": "nosniff", 1768 | "actionTokenGeneratedByAdminLifespan": "43200", 1769 | "bruteForceProtected": "false", 1770 | "_browser_header.contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", 1771 | "waitIncrementSeconds": "60" 1772 | }, 1773 | "keycloakVersion": "3.4.3.Final" 1774 | } -------------------------------------------------------------------------------- /docs/realm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/docs/realm.png -------------------------------------------------------------------------------- /docs/realm_email.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/docs/realm_email.png -------------------------------------------------------------------------------- /docs/role_public.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/docs/role_public.png -------------------------------------------------------------------------------- /docs/see_your_email.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/docs/see_your_email.png -------------------------------------------------------------------------------- /docs/service_roles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/docs/service_roles.png -------------------------------------------------------------------------------- /docs/sign_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/docs/sign_up.png -------------------------------------------------------------------------------- /docs/user_created.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/docs/user_created.png -------------------------------------------------------------------------------- /docs/users.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/docs/users.png -------------------------------------------------------------------------------- /keycloak.json: -------------------------------------------------------------------------------- 1 | { 2 | "realm": "realm_gem", 3 | "auth-server-url": "https://sso-desenv.ima.sp.gov.br/auth", 4 | "ssl-required": "external", 5 | "resource": "my_application", 6 | "credentials": { 7 | "secret": "459db71a-7cd3-4413-bcb0-2ae2b0c8261a" 8 | }, 9 | "confidential-port": 0, 10 | "policy-enforcer": {} 11 | } -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/lib/assets/.keep -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/lib/tasks/.keep -------------------------------------------------------------------------------- /log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/log/.keep -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my_application", 3 | "private": true, 4 | "dependencies": {} 5 | } 6 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/public/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/public/favicon.ico -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /test/application_system_test_case.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase 4 | driven_by :selenium, using: :chrome, screen_size: [1400, 1400] 5 | end 6 | -------------------------------------------------------------------------------- /test/controllers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/test/controllers/.keep -------------------------------------------------------------------------------- /test/fixtures/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/test/fixtures/.keep -------------------------------------------------------------------------------- /test/fixtures/files/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/test/fixtures/files/.keep -------------------------------------------------------------------------------- /test/helpers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/test/helpers/.keep -------------------------------------------------------------------------------- /test/integration/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/test/integration/.keep -------------------------------------------------------------------------------- /test/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/test/mailers/.keep -------------------------------------------------------------------------------- /test/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/test/models/.keep -------------------------------------------------------------------------------- /test/system/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/test/system/.keep -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['RAILS_ENV'] ||= 'test' 2 | require File.expand_path('../../config/environment', __FILE__) 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 7 | fixtures :all 8 | 9 | # Add more helper methods to be used by all tests here... 10 | end 11 | -------------------------------------------------------------------------------- /tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/tmp/.keep -------------------------------------------------------------------------------- /vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagov/example-gem-keycloak/0d268ad195378b6e07283f6dd0bcfae6505a3c90/vendor/.keep --------------------------------------------------------------------------------