mirror of
https://github.com/empayre/fleet.git
synced 2024-11-07 17:28:54 +00:00
368b9d774c
This PR partially addresses #1456, providing SSO SAML support. The flow of the code is as follows. A Kolide user attempts to access a protected resource and is directed to log in. If SSO identity providers (IDP) have been configured by an admin, the user is presented with SSO log in. The user selects SSO, which invokes a call the InitiateSSO passing the URL of the protected resource that the user was originally trying access. Kolide server loads the IDP metadata and caches it along with the URL. We then build an auth request URL for the IDP which is returned to the front end. The IDP calls the server, invoking CallbackSSO with the auth response. We extract the original request id from the response and use it to fetch the cached metadata and the URL. We check the signature of the response, and validate the timestamps. If everything passes we get the user id from the IDP response and use it to create a login session. We then build a page which executes some javascript that will write the token to web local storage, and redirect to the original URL. I've created a test web page in tools/app/authtest.html that can be used to test and debug new IDP's which also illustrates how a front end would interact with the IDP and the server. This page can be loaded by starting Kolide with the environment variable KOLIDE_TEST_PAGE_PATH to the full path of the page and then accessed at https://localhost:8080/test
109 lines
4.5 KiB
HTML
109 lines
4.5 KiB
HTML
<html>
|
|
<head>
|
|
<style>
|
|
div.columns { width: 900px; padding-top: 10px; padding-bottom: 10px; }
|
|
div.columns div { width: 300px; float: left; }
|
|
div.clear { clear: both; }
|
|
div.content { width: 900px; padding-top: 10px; padding-bottom: 10px; }
|
|
</style>
|
|
<script
|
|
src="https://code.jquery.com/jquery-3.2.1.js"
|
|
integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="
|
|
crossorigin="anonymous">
|
|
</script>
|
|
<script>
|
|
|
|
$(document).ready(function(){
|
|
// User agent handling for SSO
|
|
|
|
// Check for existing session token indicating user has already started SSO process.
|
|
// If the token exists, it is used to fetch the same user info/token as the
|
|
// normal login process, albeit via the different SSO login endpoint. Note the session token only
|
|
// persists for a few minutes on the server side, and, when we're done
|
|
// we always delete the token in the user agent. We use the session token
|
|
// to keep track of state from the user agent (Kolide SPA), the service provider
|
|
// (Kolide back end), to the identity provider (IDP) and back.
|
|
var sessionToken = localStorage.getItem("KOLIDE::auth_token")
|
|
if( sessionToken != null ) {
|
|
console.log("user should be authenticated, fetching user with token " + sessionToken);
|
|
$.ajax({
|
|
type: "GET",
|
|
url: "https://localhost:8080/api/v1/kolide/me",
|
|
headers: {"Authorization": "Bearer " + sessionToken},
|
|
contentType: "text/plain;",
|
|
dataType: "json",
|
|
success: function(data) {
|
|
// We've successfully created a login session with a token that
|
|
// we can use in subsequent api calls to Kolide.
|
|
console.log("sso login succeeded " + data);
|
|
$("#displayarea").empty();
|
|
$("#displayarea").append(
|
|
"<h3>Authentication Succeeded</h3>" +
|
|
"<p>Token: " + localStorage.getItem("KOLIDE::auth_token").substring(0, 16) + "..." + "</p>" +
|
|
"<p>User: " + data.user.email + "</p>"
|
|
);
|
|
// print user stuff
|
|
},
|
|
error: function(err) {
|
|
console.log("sso login failed " + data);
|
|
$("#displayarea").empty();
|
|
$("#displayarea").append(
|
|
"<h3>Auth Failed</h3>"
|
|
);
|
|
}
|
|
});
|
|
console.log("removing token " + localStorage.getItem("ssoSession"));
|
|
localStorage.removeItem("ssoSession");
|
|
}
|
|
// Single sign on invocation. User agent chooses single sign on for a particular
|
|
// IDP trigger the following post.
|
|
$(".clicker").click(function(e){
|
|
e.preventDefault();
|
|
|
|
$.ajax({
|
|
type: "POST",
|
|
url: "https://localhost:8080/api/v1/kolide/sso",
|
|
data: JSON.stringify(
|
|
{
|
|
// supply the url of the resource user was trying to access when
|
|
// prompted for login
|
|
relay_url: $("#relay").val(),
|
|
}
|
|
),
|
|
contentType: "text/plain;",
|
|
dataType: "json",
|
|
success: function(data){
|
|
console.log(data);
|
|
// on success we redirect to IDP URL which is in response
|
|
window.location.href = data.url;
|
|
},
|
|
error: function(errMsg) {console.log(errMsg);}
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<h3>Single Sign On Test Page</h3>
|
|
<div class="content">
|
|
This page is used to test single sign on identity providers. The <strong>Relay URL</strong> field contains
|
|
the URL of the Kolide resource to invoke after authentication with the IDP. It defaults to this page.
|
|
Click <a class='clicker' href='#'>Request Authorization</a>
|
|
to trigger the authorization process. The browser's javascript console may contain useful
|
|
debugging information. The <a href="https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/">SAML Tracer</a> add-on
|
|
for Firefox is also useful in diagnosing problems with a particular identity provider.
|
|
</div>
|
|
<div class="columns">
|
|
<div>
|
|
Relay URL:
|
|
</div>
|
|
<div>
|
|
<input type="text" name="relay" id="relay" value="/test"/>
|
|
</div>
|
|
</div>
|
|
<div class="clear"></div>
|
|
<p><a class='clicker' href='#'>Request Authorization</a></p>
|
|
<div id="displayarea"></div>
|
|
</body>
|
|
</html>
|