1
1
// Global variables
2
- var PrincipalArn = '' ;
3
- var RoleArn = '' ;
4
2
var FileName = 'credentials.txt' ;
5
3
6
- // When this background process starts; Load Principal ARN, Role ARN, and output FileName
4
+ // When this background process starts, load variables from chrome storage
7
5
// from saved Extension Options
8
6
loadItemsFromStorage ( ) ;
9
7
// Additionaly on start of the background process it is checked if this extension can be activated
@@ -43,13 +41,47 @@ function removeOnBeforeRequestEventListener() {
43
41
// Callback function for the webRequest OnBeforeRequest EventListener
44
42
// This function runs on each request to https://signin.aws.amazon.com/saml
45
43
function onBeforeRequestEvent ( details ) {
44
+ // Decode base64 SAML assertion in the request
45
+ var samlXmlDoc = decodeURIComponent ( unescape ( window . atob ( details . requestBody . formData . SAMLResponse [ 0 ] ) ) ) ;
46
+ // Convert XML String to DOM
47
+ parser = new DOMParser ( )
48
+ domDoc = parser . parseFromString ( samlXmlDoc , "text/xml" ) ;
49
+ // Get a list of claims (= AWS roles) from the SAML assertion
50
+ var roleDomNodes = domDoc . querySelectorAll ( '[Name="https://aws.amazon.com/SAML/Attributes/Role"]' ) [ 0 ] . childNodes
51
+ // Parse the PrincipalArn and the RoleArn from the SAML Assertion.
52
+ var PrincipalArn = '' ;
53
+ var RoleArn = '' ;
54
+ var SAMLAssertion = details . requestBody . formData . SAMLResponse [ 0 ] ;
55
+ // If there is more than 1 role in the claim, look at the 'roleIndex' HTTP Form data parameter to determine the role to assume
56
+ if ( roleDomNodes . length > 1 && "roleIndex" in details . requestBody . formData ) {
57
+ for ( i = 0 ; i < roleDomNodes . length ; i ++ ) {
58
+ var nodeValue = roleDomNodes [ i ] . innerHTML ;
59
+ if ( nodeValue . indexOf ( details . requestBody . formData . roleIndex [ 0 ] ) > - 1 ) {
60
+ // This DomNode holdes the data for the role to assume. Use these details for the assumeRoleWithSAML API call
61
+ PrincipalArn = nodeValue . substring ( 0 , nodeValue . indexOf ( ',' ) ) ;
62
+ RoleArn = nodeValue . substring ( nodeValue . indexOf ( ',' ) + 1 ) ;
63
+ assumeRoleWithSAML ( PrincipalArn , RoleArn , SAMLAssertion ) ;
64
+ }
65
+ }
66
+ }
67
+ // If there is just 1 role in the claim there will be no 'roleIndex' in the form data.
68
+ else if ( roleDomNodes . length == 1 ) {
69
+ // When there is just 1 role in the claim, use these details for the assumeRoleWithSAML API call
70
+ PrincipalArn = roleDomNodes [ 0 ] . substring ( 0 , roleDomNodes [ 0 ] . indexOf ( ',' ) ) ;
71
+ RoleArn = roleDomNodes [ 0 ] . substring ( roleDomNodes [ 0 ] . indexOf ( ',' ) + 1 ) ;
72
+ assumeRoleWithSAML ( PrincipalArn , RoleArn , SAMLAssertion ) ;
73
+ }
74
+ }
75
+
76
+
77
+ // Function called from onBeforeRequestEvent when SAMLProvider, Role and SAMLAssertion is available
78
+ function assumeRoleWithSAML ( PrincipalArn , RoleArn , SAMLAssertion ) {
46
79
// Set parameters needed for assumeRoleWithSAML method
47
80
var params = {
48
81
PrincipalArn : PrincipalArn ,
49
82
RoleArn : RoleArn ,
50
- SAMLAssertion : details . requestBody . formData . SAMLResponse [ 0 ] ,
83
+ SAMLAssertion : SAMLAssertion ,
51
84
} ;
52
-
53
85
// Call STS API from AWS
54
86
var sts = new AWS . STS ( ) ;
55
87
sts . assumeRoleWithSAML ( params , function ( err , data ) {
@@ -65,7 +97,6 @@ function onBeforeRequestEvent(details) {
65
97
chrome . downloads . download ( { url : doc , filename : FileName , conflictAction : 'overwrite' , saveAs : false } ) ;
66
98
}
67
99
} ) ;
68
-
69
100
}
70
101
71
102
@@ -96,12 +127,8 @@ chrome.runtime.onMessage.addListener(
96
127
97
128
function loadItemsFromStorage ( ) {
98
129
chrome . storage . sync . get ( {
99
- PrincipalArn : '' ,
100
- RoleArn : '' ,
101
130
FileName : 'credentials.txt'
102
131
} , function ( items ) {
103
- PrincipalArn = items . PrincipalArn ;
104
- RoleArn = items . RoleArn ;
105
132
FileName = items . FileName ;
106
133
} ) ;
107
134
}
0 commit comments