Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
go-sso
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
6
Issues
6
List
Boards
Labels
Service Desk
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
id
go-sso
Commits
86a88695
Commit
86a88695
authored
Nov 03, 2018
by
ale
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support deploying the SSO server below a URL path prefix
Likely fixes issue
#7
(untested).
parent
e502d9e2
Pipeline
#1476
passed with stages
in 1 minute and 33 seconds
Changes
10
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
73 additions
and
47 deletions
+73
-47
server/bindata.go
server/bindata.go
+17
-17
server/config.go
server/config.go
+8
-0
server/http.go
server/http.go
+22
-16
server/login.go
server/login.go
+13
-1
server/sri.py
server/sri.py
+1
-1
server/templates/login_otp.html
server/templates/login_otp.html
+1
-1
server/templates/login_password.html
server/templates/login_password.html
+1
-1
server/templates/login_u2f.html
server/templates/login_u2f.html
+1
-1
server/templates/logout.html
server/templates/logout.html
+1
-1
server/templates/page.html
server/templates/page.html
+8
-8
No files found.
server/bindata.go
View file @
86a88695
...
...
@@ -1107,7 +1107,7 @@ func staticJsU2fJs() (*asset, error) {
var
_templatesLogin_otpHtml
=
[]
byte
(
`{{template "header" .}}
<form class="form-signin" action="/login" method="post">
<form class="form-signin" action="
{{.URLPrefix}}
/login" method="post">
{{.CSRFField}}
<h1 class="form-signin-heading">Sign In / OTP</h1>
...
...
@@ -1138,14 +1138,14 @@ func templatesLogin_otpHtml() (*asset, error) {
return
nil
,
err
}
info
:=
bindataFileInfo
{
name
:
"templates/login_otp.html"
,
size
:
5
29
,
mode
:
os
.
FileMode
(
420
),
modTime
:
time
.
Unix
(
1535013418
,
0
)}
info
:=
bindataFileInfo
{
name
:
"templates/login_otp.html"
,
size
:
5
43
,
mode
:
os
.
FileMode
(
420
),
modTime
:
time
.
Unix
(
1541234791
,
0
)}
a
:=
&
asset
{
bytes
:
bytes
,
info
:
info
}
return
a
,
nil
}
var
_templatesLogin_passwordHtml
=
[]
byte
(
`{{template "header" .}}
<form class="form-signin" action="/login" method="post">
<form class="form-signin" action="
{{.URLPrefix}}
/login" method="post">
{{.CSRFField}}
<h1 class="form-signin-heading">Sign In</h1>
...
...
@@ -1198,14 +1198,14 @@ func templatesLogin_passwordHtml() (*asset, error) {
return
nil
,
err
}
info
:=
bindataFileInfo
{
name
:
"templates/login_password.html"
,
size
:
10
74
,
mode
:
os
.
FileMode
(
420
),
modTime
:
time
.
Unix
(
1535013418
,
0
)}
info
:=
bindataFileInfo
{
name
:
"templates/login_password.html"
,
size
:
10
88
,
mode
:
os
.
FileMode
(
420
),
modTime
:
time
.
Unix
(
1541234797
,
0
)}
a
:=
&
asset
{
bytes
:
bytes
,
info
:
info
}
return
a
,
nil
}
var
_templatesLogin_u2fHtml
=
[]
byte
(
`{{template "header" .}}
<form class="form-signin" id="u2fForm" action="/login" method="post">
<form class="form-signin" id="u2fForm" action="
{{.URLPrefix}}
/login" method="post">
{{.CSRFField}}
<input type="hidden" id="u2fResponseField" name="u2f_response" value="">
...
...
@@ -1238,7 +1238,7 @@ func templatesLogin_u2fHtml() (*asset, error) {
return
nil
,
err
}
info
:=
bindataFileInfo
{
name
:
"templates/login_u2f.html"
,
size
:
498
,
mode
:
os
.
FileMode
(
420
),
modTime
:
time
.
Unix
(
1535013418
,
0
)}
info
:=
bindataFileInfo
{
name
:
"templates/login_u2f.html"
,
size
:
512
,
mode
:
os
.
FileMode
(
420
),
modTime
:
time
.
Unix
(
1541234815
,
0
)}
a
:=
&
asset
{
bytes
:
bytes
,
info
:
info
}
return
a
,
nil
}
...
...
@@ -1286,7 +1286,7 @@ var _templatesLogoutHtml = []byte(`{{template "header" .}}
</div>
{{else}}
<form class="form-signin" action="/logout" method="post">
<form class="form-signin" action="
{{.URLPrefix}}
/logout" method="post">
{{.CSRFField}}
<h1 class="form-signin-heading">Sign Out</h1>
...
...
@@ -1319,7 +1319,7 @@ func templatesLogoutHtml() (*asset, error) {
return
nil
,
err
}
info
:=
bindataFileInfo
{
name
:
"templates/logout.html"
,
size
:
15
10
,
mode
:
os
.
FileMode
(
420
),
modTime
:
time
.
Unix
(
1535013418
,
0
)}
info
:=
bindataFileInfo
{
name
:
"templates/logout.html"
,
size
:
15
24
,
mode
:
os
.
FileMode
(
420
),
modTime
:
time
.
Unix
(
1541234913
,
0
)}
a
:=
&
asset
{
bytes
:
bytes
,
info
:
info
}
return
a
,
nil
}
...
...
@@ -1330,8 +1330,8 @@ var _templatesPageHtml = []byte(`{{define "header"}}<!DOCTYPE html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
{{if .U2FSignRequest}}<meta name="u2f_request" value="{{json .U2FSignRequest}}">{{end}}
<link rel="stylesheet" href="/static/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M">
<link rel="stylesheet" href="/static/css/signin.css" integrity="sha384-9Y3UkAyM3svAuamEoaXIxe+1MqBKJdZtL8S1FZjvE1XqkICDH7DTXNavnFV8Uk2o">
<link rel="stylesheet" href="
{{.URLPrefix}}
/static/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M">
<link rel="stylesheet" href="
{{.URLPrefix}}
/static/css/signin.css" integrity="sha384-9Y3UkAyM3svAuamEoaXIxe+1MqBKJdZtL8S1FZjvE1XqkICDH7DTXNavnFV8Uk2o">
<title>Sign In</title>
</head>
...
...
@@ -1342,15 +1342,15 @@ var _templatesPageHtml = []byte(`{{define "header"}}<!DOCTYPE html>
{{define "footer"}}
</div>
<script src="/static/js/jquery-3.2.1.min.js" integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f"></script>
<script src="/static/js/popper-1.11.0.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4"></script>
<script src="/static/js/bootstrap-4.0.0-beta.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1"></script>
<script src="
{{.URLPrefix}}
/static/js/jquery-3.2.1.min.js" integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f"></script>
<script src="
{{.URLPrefix}}
/static/js/popper-1.11.0.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4"></script>
<script src="
{{.URLPrefix}}
/static/js/bootstrap-4.0.0-beta.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1"></script>
{{if .U2FSignRequest}}
<script src="/static/js/u2f-api.js" integrity="sha384-9ChevE6pp8ArGK03HgolnFjZbF3webZQtYkwcabzbcI28Lx1/2x2j2fbaAWD4cgR"></script>
<script src="/static/js/u2f.js" integrity="sha384-7zZy25ajTABErGlCQgcyRDpQDS9QVZv9o+95IfvCjWftQe20f411F1a39Ge5xmCe"></script>
<script src="
{{.URLPrefix}}
/static/js/u2f-api.js" integrity="sha384-9ChevE6pp8ArGK03HgolnFjZbF3webZQtYkwcabzbcI28Lx1/2x2j2fbaAWD4cgR"></script>
<script src="
{{.URLPrefix}}
/static/js/u2f.js" integrity="sha384-7zZy25ajTABErGlCQgcyRDpQDS9QVZv9o+95IfvCjWftQe20f411F1a39Ge5xmCe"></script>
{{end}}
{{if .IncludeLogoutScripts}}
<script src="/static/js/logout.js" integrity="sha384-lChVngGLNFXetIJTSxc+scDpi1vsBL+7Xa4r2uZpQFP/6Y2z9eCDXe/Y4IUdklRD"></script>
<script src="
{{.URLPrefix}}
/static/js/logout.js" integrity="sha384-lChVngGLNFXetIJTSxc+scDpi1vsBL+7Xa4r2uZpQFP/6Y2z9eCDXe/Y4IUdklRD"></script>
{{end}}
</body>
</html>
...
...
@@ -1367,7 +1367,7 @@ func templatesPageHtml() (*asset, error) {
return
nil
,
err
}
info
:=
bindataFileInfo
{
name
:
"templates/page.html"
,
size
:
1
617
,
mode
:
os
.
FileMode
(
420
),
modTime
:
time
.
Unix
(
1541228908
,
0
)}
info
:=
bindataFileInfo
{
name
:
"templates/page.html"
,
size
:
1
729
,
mode
:
os
.
FileMode
(
420
),
modTime
:
time
.
Unix
(
1541234783
,
0
)}
a
:=
&
asset
{
bytes
:
bytes
,
info
:
info
}
return
a
,
nil
}
...
...
server/config.go
View file @
86a88695
...
...
@@ -4,6 +4,7 @@ import (
"errors"
"log"
"regexp"
"strings"
"time"
"github.com/gorilla/securecookie"
...
...
@@ -34,6 +35,7 @@ type Config struct {
CSRFSecret
string
`yaml:"csrf_secret"`
AuthService
string
`yaml:"auth_service"`
U2FAppID
string
`yaml:"u2f_app_id"`
URLPrefix
string
`yaml:"url_path_prefix"`
DeviceManager
*
device
.
Config
`yaml:"device_manager"`
KeyStore
*
clientutil
.
BackendConfig
`yaml:"keystore"`
...
...
@@ -57,6 +59,12 @@ func (c *Config) valid() error {
if
c
.
AuthService
==
""
{
return
errors
.
New
(
"auth_service is empty"
)
}
if
c
.
U2FAppID
!=
""
&&
!
strings
.
HasPrefix
(
c
.
U2FAppID
,
"https://"
)
{
return
errors
.
New
(
"u2f_app_id does not start with https://"
)
}
if
c
.
URLPrefix
!=
""
&&
!
strings
.
HasPrefix
(
c
.
URLPrefix
,
"/"
)
{
return
errors
.
New
(
"url_path_prefix does not start with /"
)
}
// Some things we can autogenerate, but for testing purposes
// only. Print a warning.
...
...
server/http.go
View file @
86a88695
...
...
@@ -90,6 +90,7 @@ type Server struct {
keystore
ksclient
.
Client
csrfSecret
[]
byte
tpl
*
template
.
Template
urlPrefix
string
}
func
sl2bl
(
sl
[]
string
)
[][]
byte
{
...
...
@@ -102,19 +103,21 @@ func sl2bl(sl []string) [][]byte {
// New returns a new Server.
func
New
(
loginService
*
LoginService
,
authClient
authclient
.
Client
,
config
*
Config
)
(
*
Server
,
error
)
{
urlPrefix
:=
strings
.
TrimRight
(
config
.
URLPrefix
,
"/"
)
sessionSecrets
:=
sl2bl
(
config
.
SessionSecrets
)
store
:=
sessions
.
NewCookieStore
(
sessionSecrets
...
)
store
.
Options
=
&
sessions
.
Options
{
HttpOnly
:
true
,
Secure
:
true
,
MaxAge
:
0
,
Path
:
"/"
,
Path
:
urlPrefix
+
"/"
,
}
s
:=
&
Server
{
authSessionLifetime
:
defaultAuthSessionLifetime
,
authSessionStore
:
store
,
loginService
:
loginService
,
urlPrefix
:
urlPrefix
,
tpl
:
parseEmbeddedTemplates
(),
}
if
config
.
CSRFSecret
!=
""
{
...
...
@@ -137,7 +140,7 @@ func New(loginService *LoginService, authClient authclient.Client, config *Confi
if
err
!=
nil
{
return
nil
,
err
}
s
.
loginHandler
=
newLoginHandler
(
s
.
loginCallback
,
devMgr
,
authClient
,
config
.
AuthService
,
config
.
U2FAppID
,
s
.
tpl
,
sessionSecrets
...
)
s
.
loginHandler
=
newLoginHandler
(
s
.
loginCallback
,
devMgr
,
authClient
,
config
.
AuthService
,
config
.
U2FAppID
,
config
.
URLPrefix
,
s
.
tpl
,
sessionSecrets
...
)
return
s
,
nil
}
...
...
@@ -182,17 +185,10 @@ func (h *Server) withAuth(f func(http.ResponseWriter, *http.Request, *authSessio
if
err
:=
httpSession
.
Save
(
req
,
w
);
err
!=
nil
{
log
.
Printf
(
"error saving session: %v"
,
err
)
}
http
.
Redirect
(
w
,
req
,
makeLoginURL
(
req
),
http
.
StatusFound
)
http
.
Redirect
(
w
,
req
,
h
.
loginHandler
.
makeLoginURL
(
req
),
http
.
StatusFound
)
})
}
func
makeLoginURL
(
req
*
http
.
Request
)
string
{
// Just concatenate path and raw request string.
v
:=
make
(
url
.
Values
)
v
.
Set
(
"r"
,
req
.
URL
.
Path
+
"?"
+
req
.
URL
.
RawQuery
)
return
"/login?"
+
v
.
Encode
()
}
// Homepage handler. Authorizes an authenticated user to a service by
// signing a token with the user's identity. The client is redirected
// back to the service, with the signed token.
...
...
@@ -308,14 +304,24 @@ func (h *Server) handleExchange(w http.ResponseWriter, req *http.Request) {
io
.
WriteString
(
w
,
token
)
// nolint
}
func
(
h
*
Server
)
urlFor
(
path
string
)
string
{
return
h
.
urlPrefix
+
path
}
// Handler returns the http.Handler for the SSO server application.
func
(
h
*
Server
)
Handler
()
http
.
Handler
{
// The root HTTP handler. This must be a gorilla/mux.Router since
// sessions depend on it.
//
// If a URL prefix is set, we can't just add a StripPrefix in
// front of everything, as the handlers need access to the
// actual full request URL, so we just inject the prefix
// everywhere.
root
:=
mux
.
NewRouter
()
// Serve static content to anyone.
root
.
PathPrefix
(
"/static/"
)
.
Handler
(
http
.
StripPrefix
(
"/static/"
,
http
.
FileServer
(
&
assetfs
.
AssetFS
{
staticPath
:=
h
.
urlFor
(
"/static/"
)
root
.
PathPrefix
(
staticPath
)
.
Handler
(
http
.
StripPrefix
(
staticPath
,
http
.
FileServer
(
&
assetfs
.
AssetFS
{
Asset
:
Asset
,
AssetDir
:
AssetDir
,
AssetInfo
:
AssetInfo
,
...
...
@@ -325,8 +331,8 @@ func (h *Server) Handler() http.Handler {
// Build the main IDP application router, with optional CSRF
// protection.
m
:=
http
.
NewServeMux
()
m
.
Handle
(
"/login"
,
h
.
loginHandler
)
m
.
Handle
(
"/logout"
,
h
.
withAuth
(
h
.
handleLogout
))
m
.
Handle
(
h
.
urlFor
(
"/login"
)
,
h
.
loginHandler
)
m
.
Handle
(
h
.
urlFor
(
"/logout"
)
,
h
.
withAuth
(
h
.
handleLogout
))
idph
:=
http
.
Handler
(
m
)
if
h
.
csrfSecret
!=
nil
{
idph
=
csrf
.
Protect
(
h
.
csrfSecret
)(
idph
)
...
...
@@ -338,9 +344,9 @@ func (h *Server) Handler() http.Handler {
ssoh
:=
h
.
withAuth
(
h
.
handleHomepage
)
userh
:=
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
switch
{
case
r
.
Method
==
"GET"
&&
r
.
URL
.
Path
==
"/"
:
case
r
.
Method
==
"GET"
&&
r
.
URL
.
Path
==
h
.
urlFor
(
"/"
)
:
ssoh
.
ServeHTTP
(
w
,
r
)
case
r
.
URL
.
Path
==
"/exchange"
:
case
r
.
URL
.
Path
==
h
.
urlFor
(
"/exchange"
)
:
h
.
handleExchange
(
w
,
r
)
default
:
idph
.
ServeHTTP
(
w
,
r
)
...
...
@@ -348,7 +354,7 @@ func (h *Server) Handler() http.Handler {
})
// User-facing routes require cache-busting and CSP headers.
root
.
PathPrefix
(
"/"
)
.
Handler
(
withDynamicHeaders
(
userh
))
root
.
PathPrefix
(
h
.
urlFor
(
"/"
)
)
.
Handler
(
withDynamicHeaders
(
userh
))
return
root
}
...
...
server/login.go
View file @
86a88695
...
...
@@ -9,6 +9,7 @@ import (
"html/template"
"log"
"net/http"
"net/url"
"strings"
"time"
...
...
@@ -73,6 +74,7 @@ type loginHandler struct {
authClient
authclient
.
Client
authService
string
u2fAppID
string
urlPrefix
string
devMgr
*
device
.
Manager
loginCallback
loginCallbackFunc
loginSessionStore
sessions
.
Store
...
...
@@ -81,7 +83,7 @@ type loginHandler struct {
// NewLoginHandler will wrap an http.Handler with the login workflow,
// invoking it only on successful login.
func
newLoginHandler
(
okHandler
loginCallbackFunc
,
devMgr
*
device
.
Manager
,
authClient
authclient
.
Client
,
authService
,
u2fAppID
string
,
tpl
*
template
.
Template
,
keyPairs
...
[]
byte
)
*
loginHandler
{
func
newLoginHandler
(
okHandler
loginCallbackFunc
,
devMgr
*
device
.
Manager
,
authClient
authclient
.
Client
,
authService
,
u2fAppID
,
urlPrefix
string
,
tpl
*
template
.
Template
,
keyPairs
...
[]
byte
)
*
loginHandler
{
store
:=
sessions
.
NewCookieStore
(
keyPairs
...
)
store
.
Options
=
&
sessions
.
Options
{
HttpOnly
:
true
,
...
...
@@ -92,6 +94,7 @@ func newLoginHandler(okHandler loginCallbackFunc, devMgr *device.Manager, authCl
authClient
:
authClient
,
authService
:
authService
,
u2fAppID
:
u2fAppID
,
urlPrefix
:
strings
.
TrimRight
(
urlPrefix
,
"/"
),
devMgr
:
devMgr
,
loginCallback
:
okHandler
,
loginSessionStore
:
store
,
...
...
@@ -291,10 +294,19 @@ func (l *loginHandler) makeAuthRequest(w http.ResponseWriter, req *http.Request,
return
l
.
authClient
.
Authenticate
(
req
.
Context
(),
&
ar
)
}
// Return a (relative) URL that will redirect the user to the login
// page and set the continue token to the original requested URL.
func
(
l
*
loginHandler
)
makeLoginURL
(
req
*
http
.
Request
)
string
{
v
:=
make
(
url
.
Values
)
v
.
Set
(
"r"
,
req
.
URL
.
Path
+
"?"
+
req
.
URL
.
RawQuery
)
return
fmt
.
Sprintf
(
"%s/login?%s"
,
l
.
urlPrefix
,
v
.
Encode
())
}
// Renders a template to a buffer, with a return value that makes it
// convenient to use in login handlers.
func
(
l
*
loginHandler
)
executeTemplateToBuffer
(
req
*
http
.
Request
,
templateName
string
,
data
map
[
string
]
interface
{})
(
loginState
,
[]
byte
,
error
)
{
data
[
"CSRFField"
]
=
csrf
.
TemplateField
(
req
)
data
[
"URLPrefix"
]
=
l
.
urlPrefix
var
buf
bytes
.
Buffer
if
err
:=
l
.
tpl
.
ExecuteTemplate
(
&
buf
,
templateName
,
data
);
err
!=
nil
{
return
loginStateNone
,
nil
,
err
...
...
server/sri.py
View file @
86a88695
...
...
@@ -12,7 +12,7 @@ import sys
from
hashlib
import
sha384
script_rx
=
re
.
compile
(
r
'<(?:script|link rel="stylesheet")[^>]*(?:src|href)="([^"]+)"[^>]*>'
)
script_rx
=
re
.
compile
(
r
'<(?:script|link rel="stylesheet")[^>]*(?:src|href)="(
?:{{.URLPrefix}})?(
[^"]+)"[^>]*>'
)
integrity_rx
=
re
.
compile
(
r
' +integrity="[^"]*"'
)
...
...
server/templates/login_otp.html
View file @
86a88695
{{template "header" .}}
<form
class=
"form-signin"
action=
"/login"
method=
"post"
>
<form
class=
"form-signin"
action=
"
{{.URLPrefix}}
/login"
method=
"post"
>
{{.CSRFField}}
<h1
class=
"form-signin-heading"
>
Sign In / OTP
</h1>
...
...
server/templates/login_password.html
View file @
86a88695
{{template "header" .}}
<form
class=
"form-signin"
action=
"/login"
method=
"post"
>
<form
class=
"form-signin"
action=
"
{{.URLPrefix}}
/login"
method=
"post"
>
{{.CSRFField}}
<h1
class=
"form-signin-heading"
>
Sign In
</h1>
...
...
server/templates/login_u2f.html
View file @
86a88695
{{template "header" .}}
<form
class=
"form-signin"
id=
"u2fForm"
action=
"/login"
method=
"post"
>
<form
class=
"form-signin"
id=
"u2fForm"
action=
"
{{.URLPrefix}}
/login"
method=
"post"
>
{{.CSRFField}}
<input
type=
"hidden"
id=
"u2fResponseField"
name=
"u2f_response"
value=
""
>
...
...
server/templates/logout.html
View file @
86a88695
...
...
@@ -41,7 +41,7 @@
</div>
{{else}}
<form
class=
"form-signin"
action=
"/logout"
method=
"post"
>
<form
class=
"form-signin"
action=
"
{{.URLPrefix}}
/logout"
method=
"post"
>
{{.CSRFField}}
<h1
class=
"form-signin-heading"
>
Sign Out
</h1>
...
...
server/templates/page.html
View file @
86a88695
...
...
@@ -4,8 +4,8 @@
<meta
charset=
"utf-8"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1, shrink-to-fit=no"
>
{{if .U2FSignRequest}}
<meta
name=
"u2f_request"
value=
"{{json .U2FSignRequest}}"
>
{{end}}
<link
rel=
"stylesheet"
href=
"/static/css/bootstrap.min.css"
integrity=
"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M"
>
<link
rel=
"stylesheet"
href=
"/static/css/signin.css"
integrity=
"sha384-9Y3UkAyM3svAuamEoaXIxe+1MqBKJdZtL8S1FZjvE1XqkICDH7DTXNavnFV8Uk2o"
>
<link
rel=
"stylesheet"
href=
"
{{.URLPrefix}}
/static/css/bootstrap.min.css"
integrity=
"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M"
>
<link
rel=
"stylesheet"
href=
"
{{.URLPrefix}}
/static/css/signin.css"
integrity=
"sha384-9Y3UkAyM3svAuamEoaXIxe+1MqBKJdZtL8S1FZjvE1XqkICDH7DTXNavnFV8Uk2o"
>
<title>
Sign In
</title>
</head>
...
...
@@ -16,15 +16,15 @@
{{define "footer"}}
</div>
<script
src=
"/static/js/jquery-3.2.1.min.js"
integrity=
"sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f"
></script>
<script
src=
"/static/js/popper-1.11.0.min.js"
integrity=
"sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4"
></script>
<script
src=
"/static/js/bootstrap-4.0.0-beta.min.js"
integrity=
"sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1"
></script>
<script
src=
"
{{.URLPrefix}}
/static/js/jquery-3.2.1.min.js"
integrity=
"sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f"
></script>
<script
src=
"
{{.URLPrefix}}
/static/js/popper-1.11.0.min.js"
integrity=
"sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4"
></script>
<script
src=
"
{{.URLPrefix}}
/static/js/bootstrap-4.0.0-beta.min.js"
integrity=
"sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1"
></script>
{{if .U2FSignRequest}}
<script
src=
"/static/js/u2f-api.js"
integrity=
"sha384-9ChevE6pp8ArGK03HgolnFjZbF3webZQtYkwcabzbcI28Lx1/2x2j2fbaAWD4cgR"
></script>
<script
src=
"/static/js/u2f.js"
integrity=
"sha384-7zZy25ajTABErGlCQgcyRDpQDS9QVZv9o+95IfvCjWftQe20f411F1a39Ge5xmCe"
></script>
<script
src=
"
{{.URLPrefix}}
/static/js/u2f-api.js"
integrity=
"sha384-9ChevE6pp8ArGK03HgolnFjZbF3webZQtYkwcabzbcI28Lx1/2x2j2fbaAWD4cgR"
></script>
<script
src=
"
{{.URLPrefix}}
/static/js/u2f.js"
integrity=
"sha384-7zZy25ajTABErGlCQgcyRDpQDS9QVZv9o+95IfvCjWftQe20f411F1a39Ge5xmCe"
></script>
{{end}}
{{if .IncludeLogoutScripts}}
<script
src=
"/static/js/logout.js"
integrity=
"sha384-lChVngGLNFXetIJTSxc+scDpi1vsBL+7Xa4r2uZpQFP/6Y2z9eCDXe/Y4IUdklRD"
></script>
<script
src=
"
{{.URLPrefix}}
/static/js/logout.js"
integrity=
"sha384-lChVngGLNFXetIJTSxc+scDpi1vsBL+7Xa4r2uZpQFP/6Y2z9eCDXe/Y4IUdklRD"
></script>
{{end}}
</body>
</html>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment