lobby_boy 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/README.md +196 -0
- data/Rakefile +40 -0
- data/app/controllers/lobby_boy/session_controller.rb +93 -0
- data/app/helpers/lobby_boy/session_helper.rb +52 -0
- data/app/views/lobby_boy/_iframes.html.erb +7 -0
- data/app/views/lobby_boy/session/check.html.erb +171 -0
- data/config/initializers/omniauth.rb +4 -0
- data/config/routes.rb +6 -0
- data/lib/lobby_boy.rb +6 -0
- data/lib/lobby_boy/configuration.rb +80 -0
- data/lib/lobby_boy/engine.rb +31 -0
- data/lib/lobby_boy/omni_auth/failure_endpoint.rb +110 -0
- data/lib/lobby_boy/openid_connect/id_token.rb +39 -0
- data/lib/lobby_boy/patches/session_management.rb +45 -0
- data/lib/lobby_boy/util/uri.rb +25 -0
- data/lib/lobby_boy/version.rb +3 -0
- data/lib/tasks/lobby_boy_tasks.rake +4 -0
- metadata +118 -0
data/README.md
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
# lobby_boy
|
2
|
+
Rails engine for OpenID Connect Session Management
|
3
|
+
|
4
|
+
Assumes the use of OmniAuth and the `omniauth-openid-connect` strategy.
|
5
|
+
|
6
|
+
## Dependencies
|
7
|
+
|
8
|
+
If not present yet add the following gem:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'omniauth-openid-connect', git: 'https://github.com/jjbohn/omniauth-openid-connect.git', branch: 'master'
|
12
|
+
```
|
13
|
+
|
14
|
+
## Usage
|
15
|
+
|
16
|
+
You have to do 6 steps to enable session management in your application:
|
17
|
+
|
18
|
+
1. Mount the engine.
|
19
|
+
2. Configure lobby_boy.
|
20
|
+
3. Render lobby_boy's iframes partial in your layout.
|
21
|
+
4. Call lobby_boy's `SessionHelper#confirm_login!` when the user is logged in.
|
22
|
+
5. Call lobby_boy's `SessionHelper#logout_at_op!` when the user logs out.
|
23
|
+
6. Implement the end_session_endpoint to be used by lobby_boys Javascript.
|
24
|
+
|
25
|
+
The following sections will describe those steps in more detail.
|
26
|
+
|
27
|
+
### 1. Mount the engine
|
28
|
+
|
29
|
+
To mount the engine into your application add the following to your `config/routes.rb`:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'lobby_boy'
|
33
|
+
|
34
|
+
Rails.application.routes.draw do
|
35
|
+
mount LobbyBoy::Engine, at: '/'
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
### 2. Configure lobby_boy
|
40
|
+
|
41
|
+
The are two sections to be configured:
|
42
|
+
|
43
|
+
*client*
|
44
|
+
|
45
|
+
This refers to your application which is an OpenID Connect client.
|
46
|
+
All lobby_boy needs to know about it is its `host` and `end_session_endpoint` (i.e. logout URL).
|
47
|
+
|
48
|
+
Here are all available client options, the rest of them which are optional:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
LobbyBoy.configure_client! host: 'https://myapp.com',
|
52
|
+
end_session_endpoint: '/logout',
|
53
|
+
# (optional) Derived from host per default:
|
54
|
+
cookie_domain: "myapp.com",
|
55
|
+
# (optional) A block executed in the context of a rails controller
|
56
|
+
# which returns true if the user is logged into
|
57
|
+
# the application:
|
58
|
+
logged_in: ->() { session.include? :user },
|
59
|
+
# (optional) Seconds before the ID token's expiration at which
|
60
|
+
# to re-authenticate early:
|
61
|
+
refresh_offset: 60,
|
62
|
+
# (optional) Check the session state every 30 seconds and refresh
|
63
|
+
# if out of sync:
|
64
|
+
refresh_interval: 30,
|
65
|
+
# (optional) A .js.erb (app/views/session/_on_login.js.erb) partial
|
66
|
+
# to be rendered the code of which will be executed if the user is
|
67
|
+
# logged in automatically:
|
68
|
+
on_login_js_partial: 'session/on_login',
|
69
|
+
# (optional) A .js.erb (app/views/session/_on_logout.js.erb) partial
|
70
|
+
# to be rendered the code of which will be executed if the user is
|
71
|
+
# logged out automatically:
|
72
|
+
on_logout_js_partial: 'session/on_logout'
|
73
|
+
|
74
|
+
```
|
75
|
+
|
76
|
+
*provider*
|
77
|
+
|
78
|
+
The OpenIDConnect provider has to support Session Management too. The essential details
|
79
|
+
required for the provider are its `name` (its strategy being available under `/auth/$name`)
|
80
|
+
and the `identifier` under which your client is registered at the provider.
|
81
|
+
|
82
|
+
If the provider supports discovery this is everything. If not you will also have to configure
|
83
|
+
the `issuer`, `end_session_endpoint` and `check_session_iframe`.
|
84
|
+
|
85
|
+
For instance for **Concierge** which does not support discovery yet:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
LobbyBoy.configure_provider! name: 'concierge',
|
89
|
+
client_id: 'openproject',
|
90
|
+
issuer: 'https://concierge.openproject.com',
|
91
|
+
end_session_endpoint: '/session/end',
|
92
|
+
check_session_iframe: '/session/check']
|
93
|
+
```
|
94
|
+
|
95
|
+
### 3. Render lobby_boy's iframes partial in your layout.
|
96
|
+
|
97
|
+
Session Management requires two iframes, the relying party iframe and the OpenIDConnect provider iframe,
|
98
|
+
to be rendered at all times, on every page.
|
99
|
+
In a standard rails application you would do this by inserting the following line into
|
100
|
+
`app/views/layouts/application.html.erb`:
|
101
|
+
|
102
|
+
```
|
103
|
+
<%= render 'lobby_boy/iframes' %>
|
104
|
+
```
|
105
|
+
|
106
|
+
### 4. Call lobby_boy's `SessionHelper#confirm_login!` when the user is logged in.
|
107
|
+
|
108
|
+
The `#confirm_login!` helper stores the logged-in user's ID token in the session
|
109
|
+
and sets the `oidc_rp_state` cookie. Which means that this helper has to be called
|
110
|
+
in the context of the final action handling the user's login.
|
111
|
+
|
112
|
+
Another thing the login must do is to redirect the user to the omniauth origin.
|
113
|
+
It should do that already if implemented correctly.
|
114
|
+
|
115
|
+
For instance:
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
class SessionController < ApplicationController
|
119
|
+
include LobbyBoy::SessionHelper
|
120
|
+
|
121
|
+
def login
|
122
|
+
# existing logic:
|
123
|
+
# ...
|
124
|
+
|
125
|
+
confirm_login!
|
126
|
+
redirect_to(request.env['omniauth.origin'] || default_url)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
```
|
130
|
+
|
131
|
+
It is important that your login action redirects to `omniauth.origin` after a
|
132
|
+
successful login.
|
133
|
+
|
134
|
+
*Optional: reauthentication*
|
135
|
+
|
136
|
+
If you have to behave differently when the user is reauthenticated you can
|
137
|
+
additionally to the changes above use the reauthentication helpers.
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
class SessionController < ApplicationController
|
141
|
+
include LobbyBoy::SessionHelper
|
142
|
+
|
143
|
+
def login
|
144
|
+
# existing logic:
|
145
|
+
# ...
|
146
|
+
|
147
|
+
confirm_login!
|
148
|
+
|
149
|
+
if reauthentication?
|
150
|
+
finish_reauthentication!
|
151
|
+
else
|
152
|
+
go_on_to_do_more_stuff_not_necessary_on_reauthentication
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
### Call lobby_boy's `SessionHelper#logout_at_op!` when the user logs out.
|
158
|
+
|
159
|
+
When the user logs out of the application they should also be logged out of the
|
160
|
+
OpenID Connect provider. To do that call the `#logout_at_op!` helper in your existing logout action.
|
161
|
+
The helper will redirect the user to the provider's logout endpoint to log them out globally.
|
162
|
+
You can pass a return URL to which the provider will send the user after the logout.
|
163
|
+
|
164
|
+
For instance:
|
165
|
+
|
166
|
+
```ruby
|
167
|
+
class SessionController < ApplicationController
|
168
|
+
def logout
|
169
|
+
# The helper will return false and do nothing the provider's
|
170
|
+
# end_session_endpoint is not configured.
|
171
|
+
unless logout_at_op! root_url
|
172
|
+
redirect_to root_url
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
```
|
177
|
+
|
178
|
+
### 6. Implement the end_session_endpoint to be used by lobby_boys Javascript.
|
179
|
+
|
180
|
+
The Javascript of lobby_boy may logout the user when it realizes that
|
181
|
+
the user has been logged out at the OpenID Connect provider.
|
182
|
+
You have to implement the `end_session_endpoint` and after logging out
|
183
|
+
the user you have to call `finish_logout!` from LobbyBoy's `SessionHelper`.
|
184
|
+
|
185
|
+
For instance:
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
class SessionController < ApplicationController
|
189
|
+
include LobbyBoy::SessionHelper
|
190
|
+
|
191
|
+
def lobby_boy_logout
|
192
|
+
logout_user!
|
193
|
+
finish_logout!
|
194
|
+
end
|
195
|
+
end
|
196
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'LobbyBoy'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
29
|
+
|
30
|
+
require 'rake/testtask'
|
31
|
+
|
32
|
+
Rake::TestTask.new(:test) do |t|
|
33
|
+
t.libs << 'lib'
|
34
|
+
t.libs << 'test'
|
35
|
+
t.pattern = 'test/**/*_test.rb'
|
36
|
+
t.verbose = false
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
task :default => :test
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module LobbyBoy
|
2
|
+
class SessionController < ActionController::Base
|
3
|
+
layout false
|
4
|
+
|
5
|
+
before_filter :set_cache_buster
|
6
|
+
|
7
|
+
def check
|
8
|
+
response.headers['X-Frame-Options'] = 'SAMEORIGIN'
|
9
|
+
|
10
|
+
render_check 'init'
|
11
|
+
end
|
12
|
+
|
13
|
+
def state
|
14
|
+
current_state =
|
15
|
+
if params[:state] == 'unauthenticated'
|
16
|
+
'unauthenticated'
|
17
|
+
elsif params[:state] == 'logout'
|
18
|
+
'logout'
|
19
|
+
else
|
20
|
+
self.id_token ? 'authenticated' : 'unauthenticated'
|
21
|
+
end
|
22
|
+
|
23
|
+
render_check current_state
|
24
|
+
end
|
25
|
+
|
26
|
+
def end
|
27
|
+
cookies.delete :oidc_rp_state, domain: LobbyBoy.client.cookie_domain
|
28
|
+
|
29
|
+
redirect_to LobbyBoy.client.end_session_endpoint
|
30
|
+
end
|
31
|
+
|
32
|
+
def refresh
|
33
|
+
provider = LobbyBoy.provider.name
|
34
|
+
|
35
|
+
id_token = self.id_token
|
36
|
+
|
37
|
+
id_token_hint = id_token && id_token.jwt_token
|
38
|
+
origin = '/session/state'
|
39
|
+
|
40
|
+
params = {
|
41
|
+
prompt: 'none',
|
42
|
+
origin: origin,
|
43
|
+
id_token_hint: id_token_hint
|
44
|
+
}
|
45
|
+
|
46
|
+
redirect_to "#{omniauth_prefix}/#{provider}?#{compact_hash(params).to_query}"
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Defines used functions. All of which are only dependent on
|
51
|
+
# their input parameters and not on some random global state.
|
52
|
+
module Functions
|
53
|
+
module_function
|
54
|
+
|
55
|
+
##
|
56
|
+
# Returns a new hash only containing entries the values of which are not nil.
|
57
|
+
def compact_hash(hash)
|
58
|
+
hash.reject { |_, v| v.nil? }
|
59
|
+
end
|
60
|
+
|
61
|
+
def omniauth_prefix
|
62
|
+
::OmniAuth.config.path_prefix
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# Returns true if the user is logged in locally or false
|
67
|
+
# if they aren't or we don't know whether or not they are.
|
68
|
+
def logged_in?
|
69
|
+
instance_exec &LobbyBoy.client.logged_in
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
module InstanceMethods
|
74
|
+
def id_token
|
75
|
+
token = session['lobby_boy.id_token']
|
76
|
+
::LobbyBoy::OpenIDConnect::IdToken.new token if token
|
77
|
+
end
|
78
|
+
|
79
|
+
def render_check(state)
|
80
|
+
render 'check', locals: { state: state, logged_in: logged_in? }
|
81
|
+
end
|
82
|
+
|
83
|
+
def set_cache_buster
|
84
|
+
response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
|
85
|
+
response.headers["Pragma"] = "no-cache"
|
86
|
+
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
include Functions
|
91
|
+
include InstanceMethods
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module LobbyBoy
|
2
|
+
module SessionHelper
|
3
|
+
##
|
4
|
+
# Call in host rails controller to confirm that the user was logged in.
|
5
|
+
def confirm_login!
|
6
|
+
if LobbyBoy.configured?
|
7
|
+
session['lobby_boy.id_token'] = env['lobby_boy.id_token'].jwt_token
|
8
|
+
cookies[:oidc_rp_state] = env['lobby_boy.cookie']
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def finish_reauthentication!
|
13
|
+
redirect_to(lobby_boy_path + 'session/state')
|
14
|
+
end
|
15
|
+
|
16
|
+
def reauthentication?
|
17
|
+
env['omniauth.origin'] == '/session/state'
|
18
|
+
end
|
19
|
+
|
20
|
+
def finish_logout!
|
21
|
+
redirect_to(lobby_boy_path + 'session/state?state=logout')
|
22
|
+
end
|
23
|
+
|
24
|
+
def id_token_expired?
|
25
|
+
id_token && id_token.expires_in == 0
|
26
|
+
end
|
27
|
+
|
28
|
+
def id_token
|
29
|
+
token = session['lobby_boy.id_token']
|
30
|
+
::LobbyBoy::OpenIDConnect::IdToken.new token if token
|
31
|
+
end
|
32
|
+
|
33
|
+
def logout_at_op!(return_url = nil)
|
34
|
+
return false unless LobbyBoy.configured?
|
35
|
+
|
36
|
+
id_token_hint = id_token && id_token.jwt_token
|
37
|
+
logout_url = LobbyBoy::Util::URI.add_query_params(
|
38
|
+
LobbyBoy.provider.end_session_endpoint,
|
39
|
+
id_token_hint: id_token_hint,
|
40
|
+
post_logout_redirect_uri: return_url)
|
41
|
+
|
42
|
+
cookies.delete :oidc_rp_state, domain: LobbyBoy.client.cookie_domain
|
43
|
+
|
44
|
+
if logout_url # may be nil if not configured
|
45
|
+
redirect_to logout_url # log out at OpenIDConnect SSO provider too
|
46
|
+
true
|
47
|
+
else
|
48
|
+
false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<% if LobbyBoy.configured? %>
|
2
|
+
<% op_src = LobbyBoy.provider.check_session_iframe %>
|
3
|
+
<% rp_src = "#{LobbyBoy.client.host}/session/check" %>
|
4
|
+
|
5
|
+
<iframe id="openid_connect_provider" src="<%= op_src %>" style="display: none;"></iframe>
|
6
|
+
<iframe id="openid_connect_relying_party" src="<%= rp_src %>" style="display: none;"></iframe>
|
7
|
+
<% end %>
|
@@ -0,0 +1,171 @@
|
|
1
|
+
<%= javascript_include_tag 'js.cookie-1.5.1.min' %>
|
2
|
+
|
3
|
+
<%#
|
4
|
+
We're defining all this Javascript here as we are using URL helpers in it which
|
5
|
+
won't work in a .js.erb file without cheating.
|
6
|
+
%>
|
7
|
+
|
8
|
+
<script type="text/javascript">
|
9
|
+
Cookies.json = true;
|
10
|
+
|
11
|
+
window.parent.OpenIDConnect = new function() {
|
12
|
+
var self = this;
|
13
|
+
var locallyLoggedIn = <%= logged_in %>;
|
14
|
+
|
15
|
+
this.clientId = "<%= LobbyBoy.provider.client_id %>";
|
16
|
+
this.targetOrigin = "<%= LobbyBoy.provider.issuer %>";
|
17
|
+
this.loggedIn = (window.parent.OpenIDConnect && window.parent.OpenIDConnect.loggedIn)
|
18
|
+
|| locallyLoggedIn;
|
19
|
+
this.timerIntervalMs = <%= LobbyBoy.client.refresh_interval %> * 1000;
|
20
|
+
|
21
|
+
this.getIFrame = function(id) {
|
22
|
+
return window.parent.document.getElementById(id).contentWindow;
|
23
|
+
}
|
24
|
+
|
25
|
+
this.checkSession = function() {
|
26
|
+
var provider = self.getIFrame("openid_connect_provider");
|
27
|
+
|
28
|
+
var message = function(state) {
|
29
|
+
return self.clientId + " " + state;
|
30
|
+
};
|
31
|
+
|
32
|
+
/**
|
33
|
+
* Checking the state has two possible outcomes depending on the user's
|
34
|
+
* global login state. Either the user is logged in in which case
|
35
|
+
* their ID token is refreshed, or they aren't in which case they
|
36
|
+
* are logged out of the application and notified about the logout.
|
37
|
+
*/
|
38
|
+
var checkState = function(state) {
|
39
|
+
provider.postMessage(message(state), self.targetOrigin);
|
40
|
+
};
|
41
|
+
|
42
|
+
var state = Cookies.get("oidc_rp_state");
|
43
|
+
var time = new Date().getTime() / 1000;
|
44
|
+
var offset = <%= LobbyBoy.client.refresh_offset %>;
|
45
|
+
|
46
|
+
if (state || locallyLoggedIn) {
|
47
|
+
self.loggedIn = true;
|
48
|
+
|
49
|
+
if (state && state.expires_at - time > offset) {
|
50
|
+
checkState(state.state);
|
51
|
+
} else if (!state && locallyLoggedIn) {
|
52
|
+
/**
|
53
|
+
* This branch is executed in two cases:
|
54
|
+
*
|
55
|
+
* 1) The state cookie is not set but the user is logged into the application
|
56
|
+
*
|
57
|
+
* This can happen if the previous state cookie expired but the user's normal
|
58
|
+
* application session hasn't. At this point we don't know the user's
|
59
|
+
* global login status. Hence we force a re-authentication to sync the state.
|
60
|
+
*
|
61
|
+
* 2) The state is set but is about to expire.
|
62
|
+
*
|
63
|
+
* We prematurely 'expire' the session state to ensure that the user
|
64
|
+
* remains logged in constantly. Otherwise it could happen that the
|
65
|
+
* user is logged out briefly between the time the old ID token expired
|
66
|
+
* and the time it takes to re-authenticate.
|
67
|
+
*/
|
68
|
+
checkState("refresh.please");
|
69
|
+
}
|
70
|
+
} else {
|
71
|
+
// not logged in
|
72
|
+
}
|
73
|
+
};
|
74
|
+
|
75
|
+
this.startTimer = function() {
|
76
|
+
if (self.timerID) {
|
77
|
+
self.stopTimer(); // stop previous timer if present
|
78
|
+
}
|
79
|
+
|
80
|
+
self.timerID = setInterval(self.checkSession, self.timerIntervalMs);
|
81
|
+
};
|
82
|
+
|
83
|
+
this.stopTimer = function() {
|
84
|
+
clearInterval(self.timerID)
|
85
|
+
};
|
86
|
+
|
87
|
+
this.reauthenticate = function() {
|
88
|
+
console.log("I ought to re-authenticate");
|
89
|
+
|
90
|
+
var check_session_iframe = self.getIFrame("openid_connect_relying_party");
|
91
|
+
|
92
|
+
check_session_iframe.document.location.href = "<%= session_refresh_url %>";
|
93
|
+
};
|
94
|
+
|
95
|
+
this.onReauthenticationSuccess = function() {
|
96
|
+
console.log("Re-authenticated successfully.");
|
97
|
+
|
98
|
+
/**
|
99
|
+
* The login status will only be updated with the next call of checkSession
|
100
|
+
* which is why it may still be false at this point.
|
101
|
+
*
|
102
|
+
* If it is false it means the user may be seeing a sign-in button in the menu.
|
103
|
+
* So reload the page to have them see that they are now logged in.
|
104
|
+
*/
|
105
|
+
if (self.loggedIn === false) {
|
106
|
+
self.onLogin();
|
107
|
+
}
|
108
|
+
};
|
109
|
+
|
110
|
+
this.onReauthenticationFailure = function() {
|
111
|
+
if (self.loggedIn !== false) {
|
112
|
+
self.loggedIn = false;
|
113
|
+
self.logout();
|
114
|
+
}
|
115
|
+
};
|
116
|
+
|
117
|
+
this.onLogin = function() {
|
118
|
+
<% if LobbyBoy.client.on_login_js_partial %>
|
119
|
+
<%= render partial: LobbyBoy.client.on_login_js_partial, formats: [:js] %>
|
120
|
+
<% else %>
|
121
|
+
window.parent.document.location.reload();
|
122
|
+
<% end %>
|
123
|
+
};
|
124
|
+
|
125
|
+
this.onLogout = function() {
|
126
|
+
<% if LobbyBoy.client.on_logout_js_partial %>
|
127
|
+
<%= render partial: LobbyBoy.client.on_logout_js_partial, formats: [:js] %>
|
128
|
+
<% else %>
|
129
|
+
alert("You've been logged out.");
|
130
|
+
<% end %>
|
131
|
+
};
|
132
|
+
|
133
|
+
this.logout = function(callback) {
|
134
|
+
console.log("I ought to log out.");
|
135
|
+
|
136
|
+
var check_session_iframe = self.getIFrame("openid_connect_relying_party");
|
137
|
+
|
138
|
+
check_session_iframe.document.location.href = "<%= session_end_url %>";
|
139
|
+
};
|
140
|
+
|
141
|
+
this.receiveMessage = function(e) {
|
142
|
+
if (e.origin !== self.targetOrigin ) {
|
143
|
+
return;
|
144
|
+
}
|
145
|
+
|
146
|
+
self.state = e.data;
|
147
|
+
|
148
|
+
if (self.state == "changed") {
|
149
|
+
self.reauthenticate();
|
150
|
+
} else if (self.state == "error") {
|
151
|
+
console.log("error checking session state");
|
152
|
+
}
|
153
|
+
};
|
154
|
+
|
155
|
+
window.addEventListener("message", self.receiveMessage, false);
|
156
|
+
|
157
|
+
<% if state == 'authenticated' %>
|
158
|
+
self.onReauthenticationSuccess();
|
159
|
+
<% elsif state == 'unauthenticated' %>
|
160
|
+
self.onReauthenticationFailure();
|
161
|
+
<% elsif state == 'logout' %>
|
162
|
+
self.onLogout();
|
163
|
+
<% else %>
|
164
|
+
document.addEventListener("DOMContentLoaded", function(event) {
|
165
|
+
setTimeout(self.checkSession, 1000);
|
166
|
+
});
|
167
|
+
<% end %>
|
168
|
+
|
169
|
+
self.startTimer();
|
170
|
+
};
|
171
|
+
</script>
|