Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
daas
jwt-tokenissuer
Commits
6b5eeda7
Commit
6b5eeda7
authored
Aug 17, 2018
by
Gurvinder Singh
Browse files
added support for passing email and mas groups if enabled
parent
49bb0ebb
Changes
5
Hide whitespace changes
Inline
Side-by-side
Dockerfile
View file @
6b5eeda7
FROM
alpine:3.
5
FROM
alpine:3.
8
RUN
apk update
&&
apk add ca-certificates
...
...
@@ -7,4 +7,4 @@ COPY ./jwt-tokenissuer /bin/
USER
nobody
EXPOSE
8888
CMD
["/bin/jwt-tokenissuer", "-c", "/config/jwt"]
CMD
["/bin/jwt-tokenissuer", "-c", "/config/jwt
.json
"]
glide.yaml
View file @
6b5eeda7
...
...
@@ -10,3 +10,4 @@ import:
-
package
:
scm.uninett.no/laas/laasctl-auth
-
package
:
github.com/stretchr/testify/assert
-
package
:
golang.org/x/net/html/charset
-
package
:
github.com/davecgh/go-spew/spew
jwt.go
View file @
6b5eeda7
...
...
@@ -2,6 +2,8 @@ package main
import
(
"crypto/rsa"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
...
...
@@ -48,6 +50,12 @@ func (jwm *JWTMiddleware) JWTTokenHandler() http.Handler {
principals
=
rawGroups
.
([]
string
)
}
}
// Check if we need to get groups from MAS
if
conf
.
GetStringValue
(
"engine.mas.groups_endpoint"
)
!=
""
{
principals
=
append
(
principals
,
jwm
.
getMASgroups
(
r
.
Header
.
Get
(
"X-Dataporten-Userid-Sec"
))
...
)
}
// Get Client ID from request headers
clientID
,
clientIDFound
:=
r
.
Header
[
"X-Dataporten-Clientid"
]
if
!
clientIDFound
{
...
...
@@ -55,7 +63,11 @@ func (jwm *JWTMiddleware) JWTTokenHandler() http.Handler {
return
}
token
:=
jwm
.
getJWTToken
(
w
,
r
,
user
,
principals
,
clientID
[
0
])
// Get Email
email
:=
jwm
.
getEmail
(
r
.
Header
.
Get
(
"X-Dataporten-Token"
))
// Get the JWT token with all the required information
token
:=
jwm
.
getJWTToken
(
w
,
r
,
user
,
principals
,
clientID
[
0
],
email
)
if
token
==
nil
{
return
}
...
...
@@ -76,7 +88,8 @@ func (jwm *JWTMiddleware) getJWTToken(
r
*
http
.
Request
,
user
string
,
principals
[]
string
,
aud
string
)
[]
byte
{
aud
string
,
email
string
)
[]
byte
{
if
user
==
""
||
aud
==
""
{
auth
.
ReturnError
(
w
,
r
,
"User or Audience is empty"
,
http
.
StatusBadRequest
)
log
.
Error
(
"User or audience is empty"
)
...
...
@@ -98,6 +111,9 @@ func (jwm *JWTMiddleware) getJWTToken(
claims
.
Set
(
"principals"
,
principals
)
claims
.
Set
(
"acr_values"
,
r
.
Header
.
Get
(
"X-Dataporten-Acr"
))
claims
.
Set
(
"userid-sec"
,
r
.
Header
.
Get
(
"X-Dataporten-Userid-Sec"
))
if
email
!=
""
{
claims
.
Set
(
"email"
,
email
)
}
claims
.
SetIssuer
(
conf
.
GetStringValue
(
"engine.issuer_url"
))
claims
.
SetExpiration
(
now
.
Add
(
time
.
Duration
(
lifeTime
)
*
time
.
Second
))
...
...
@@ -110,3 +126,60 @@ func (jwm *JWTMiddleware) getJWTToken(
}
return
token
}
// Get email from UserInfo endpoint using Access Token given by GateKeeper
func
(
jwm
*
JWTMiddleware
)
getEmail
(
token
string
)
string
{
dataReq
,
err
:=
http
.
NewRequest
(
"GET"
,
conf
.
GetStringValue
(
"engine.userinfo_endpoint"
),
nil
)
if
err
!=
nil
{
log
.
Warn
(
"Failed in creating request to fecth data from DataPorten"
)
return
""
}
dataReq
.
Header
[
"Authorization"
]
=
[]
string
{
"Bearer "
+
token
}
data
:=
getReqData
(
dataReq
)
var
userInfo
interface
{}
err
=
json
.
Unmarshal
(
data
,
&
userInfo
)
if
err
!=
nil
{
log
.
Warn
(
"Failed in parsing email data from "
,
err
)
return
""
}
user
:=
userInfo
.
(
map
[
string
]
interface
{})
if
_
,
ok
:=
user
[
"email"
];
ok
{
return
user
[
"email"
]
.
(
string
)
}
log
.
Warn
(
"Failed in parsing userInfo data"
)
return
""
}
// Get MAS groups from MAS end point which provides groups in similar
// format as Dataporten
func
(
jwm
*
JWTMiddleware
)
getMASgroups
(
feideID
string
)
[]
string
{
dataReq
,
err
:=
http
.
NewRequest
(
"GET"
,
conf
.
GetStringValue
(
"engine.mas.groups_endpoint"
),
nil
)
if
err
!=
nil
{
log
.
Warn
(
"Failed in creating request to fecth data from MAS"
)
return
nil
}
// Set Feide ID as this tells to MAS Api which user data to return
dataReq
.
Header
[
"X-Dataporten-Userid-Sec"
]
=
[]
string
{
feideID
}
authVal
:=
conf
.
GetStringValue
(
"engine.mas.basic_auth.mas_creds"
)
basicAuth
:=
"Basic "
+
base64
.
StdEncoding
.
EncodeToString
([]
byte
(
authVal
))
dataReq
.
Header
[
"Authorization"
]
=
[]
string
{
basicAuth
}
data
:=
getReqData
(
dataReq
)
var
groupsData
[]
interface
{}
var
groups
[]
string
err
=
json
.
Unmarshal
(
data
,
&
groupsData
)
if
err
!=
nil
{
log
.
Debug
(
"Failed in parsing groups data from MAS"
)
return
nil
}
for
_
,
group
:=
range
groupsData
{
group
:=
group
.
(
map
[
string
]
interface
{})
if
_
,
ok
:=
group
[
"id"
];
ok
{
groups
=
append
(
groups
,
group
[
"id"
]
.
(
string
))
}
}
return
groups
}
jwt_test.go
View file @
6b5eeda7
...
...
@@ -29,14 +29,14 @@ func TestGetJWTToken(t *testing.T) {
w
:=
httptest
.
NewRecorder
()
r
:=
httptest
.
NewRequest
(
"GET"
,
"http://example.com/foo"
,
nil
)
token
:=
jwm
.
getJWTToken
(
w
,
r
,
"dummy"
,
[]
string
{
"dummyPp"
},
"dummyapp"
)
token
:=
jwm
.
getJWTToken
(
w
,
r
,
"dummy"
,
[]
string
{
"dummyPp"
},
"dummyapp"
,
"test@test.com"
)
assert
.
NotNil
(
t
,
token
)
token
=
jwm
.
getJWTToken
(
w
,
r
,
"dummy"
,
nil
,
"dummyapp"
)
token
=
jwm
.
getJWTToken
(
w
,
r
,
"dummy"
,
nil
,
"dummyapp"
,
"test@test.com"
)
assert
.
NotNil
(
t
,
token
)
token
=
jwm
.
getJWTToken
(
w
,
r
,
"dummy"
,
nil
,
""
)
token
=
jwm
.
getJWTToken
(
w
,
r
,
"dummy"
,
nil
,
""
,
"test@test.com"
)
assert
.
Nil
(
t
,
token
)
assert
.
Equal
(
t
,
http
.
StatusBadRequest
,
w
.
Code
)
token
=
jwm
.
getJWTToken
(
w
,
r
,
""
,
nil
,
""
)
token
=
jwm
.
getJWTToken
(
w
,
r
,
""
,
nil
,
""
,
"test@test.com"
)
assert
.
Nil
(
t
,
token
)
assert
.
Equal
(
t
,
http
.
StatusBadRequest
,
w
.
Code
)
}
...
...
utils.go
0 → 100644
View file @
6b5eeda7
package
main
import
(
"io/ioutil"
"net/http"
log
"github.com/Sirupsen/logrus"
)
func
getReqData
(
req
*
http
.
Request
)
[]
byte
{
client
:=
&
http
.
Client
{}
resp
,
err
:=
client
.
Do
(
req
)
if
err
!=
nil
{
log
.
Warn
(
"Failed in fetching data from "
,
req
.
URL
,
err
)
return
nil
}
if
resp
!=
nil
&&
resp
.
StatusCode
!=
200
{
log
.
Warn
(
"Failed in fetching data from "
,
req
.
URL
,
"error code "
,
resp
.
StatusCode
)
return
nil
}
body
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
resp
.
Body
.
Close
()
if
err
!=
nil
{
log
.
Warn
(
"Failed in reading body from "
,
req
.
URL
)
return
nil
}
return
body
}
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