diff options
author | Alex Rudyy <orudyy@apache.org> | 2013-04-08 11:17:41 +0000 |
---|---|---|
committer | Alex Rudyy <orudyy@apache.org> | 2013-04-08 11:17:41 +0000 |
commit | ad56a06e1f1c22a0baccb99c27a64ee9564da83b (patch) | |
tree | f6c77961e2f1fcb28e0b65368b8b7cc5a9e3ba6b /qpid/java/broker-plugins/management-http/src/main/java/resources | |
parent | d85edbc941559aa85c5a998bbb8894f13baaf81c (diff) | |
download | qpid-python-ad56a06e1f1c22a0baccb99c27a64ee9564da83b.tar.gz |
QPID-4705: Restrict access to web management interfaces to authenticated and authorised users only
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1465590 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/broker-plugins/management-http/src/main/java/resources')
4 files changed, 250 insertions, 111 deletions
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/index.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/index.html index 2fb9137ff8..a9cb580103 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/index.html +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/index.html @@ -65,7 +65,7 @@ "qpid/management/treeView", "qpid/management/controller", "qpid/common/footer", - "qpid/authorization/sasl"]); + "qpid/authorization/checkUser"]); </script> </head> diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/checkUser.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/checkUser.js new file mode 100644 index 0000000000..6b843d8d06 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/checkUser.js @@ -0,0 +1,78 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +require(["dijit/form/DropDownButton", + "dijit/TooltipDialog", + "dijit/form/TextBox", + "dojo/_base/xhr", + "dojo/dom", + "dojo/dom-construct", + "qpid/authorization/sasl", + "dojo/domReady!"], function(DropDownButton, TooltipDialog, TextBox, xhr, dom, domConstruct, sasl){ + +var dialog = new TooltipDialog({ + content: + '<strong><label for="username" style="display:inline-block;width:100px;">Username:</label></strong>' + + '<div data-dojo-type="dijit.form.TextBox" id="username"></div><br/>' + + '<strong><label for="pass" style="display:inline-block;width:100px;">Password:</label></strong>' + + '<div data-dojo-type="dijit.form.TextBox" type="password" id="pass"></div><br/>' + + '<button data-dojo-type="dijit.form.Button" type="submit" id="loginButton">Login</button>' +}); + +var button = new DropDownButton({ + label: "Login", + dropDown: dialog +}); + +var usernameSpan = domConstruct.create("span", { + innerHTML: '<strong>User: </strong> <span id="authenticatedUser"></span><a href="logout">[logout]</a>', + style: { display: "none" } +}); + + +var loginDiv = dom.byId("login"); +loginDiv.appendChild(usernameSpan); +loginDiv.appendChild(button.domNode); + +var updateUI = function updateUI(data) +{ + if(data.user) + { + dojo.byId("authenticatedUser").innerHTML = data.user; + dojo.style(button.domNode, {display: 'none'}); + dojo.style(usernameSpan, {display: 'block'}); + } + else + { + dojo.style(button.domNode, {display: 'block'}); + dojo.style(usernameSpan, {display: 'none'}); + } +}; + +dijit.byId("loginButton").on("click", function(){ + sasl.authenticate(dojo.byId("username").value, dojo.byId("pass").value, updateUI); +}); + +dialog.startup(); + +sasl.getUser(updateUI); + +});
\ No newline at end of file diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js index b4f0728685..33e736322f 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js @@ -18,10 +18,7 @@ * under the License. * */ -require(["dijit/form/DropDownButton", "dijit/TooltipDialog", "dijit/form/TextBox", - "dojo/_base/xhr", "dojox/encoding/base64", "dojox/encoding/digests/_base", "dojox/encoding/digests/MD5"]); -var button; -var usernameSpan; +define(["dojo/_base/xhr", "dojox/encoding/base64", "dojox/encoding/digests/_base", "dojox/encoding/digests/MD5"], function () { var encodeUTF8 = function encodeUTF8(str) { var byteArray = []; @@ -49,8 +46,23 @@ var decodeUTF8 = function decodeUTF8(byteArray) return decodeURIComponent(str); }; +var errorHandler = function errorHandler(error) +{ + if(error.status == 401) + { + alert("Authentication Failed"); + } + else if(error.status == 403) + { + alert("Authorization Failed"); + } + else + { + alert(error); + } +} -var saslPlain = function saslPlain(user, password) +var saslPlain = function saslPlain(user, password, callbackFunction) { var responseArray = [ 0 ].concat(encodeUTF8( user )).concat( [ 0 ] ).concat( encodeUTF8( password ) ); var plainResponse = dojox.encoding.base64.encode(responseArray); @@ -65,25 +77,10 @@ var saslPlain = function saslPlain(user, password) }, handleAs: "json", failOk: true - }).then(function() - { - updateAuthentication(); - }, - function(error) - { - if(error.status == 403) - { - alert("Authentication Failed"); - } - else - { - alert(error); - } - updateAuthentication(); - }); + }).then(callbackFunction, errorHandler); }; -var saslCramMD5 = function saslCramMD5(user, password) +var saslCramMD5 = function saslCramMD5(user, password, saslMechanism, callbackFunction) { // Using dojo.xhrGet, as very little information is being sent @@ -91,7 +88,7 @@ var saslCramMD5 = function saslCramMD5(user, password) // The URL of the request url: "rest/sasl", content: { - mechanism: "CRAM-MD5" + mechanism: saslMechanism }, handleAs: "json", failOk: true @@ -121,22 +118,7 @@ var saslCramMD5 = function saslCramMD5(user, password) }, handleAs: "json", failOk: true - }).then(function() - { - updateAuthentication(); - }, - function(error) - { - if(error.status == 403) - { - alert("Authentication Failed"); - } - else - { - alert(error); - } - updateAuthentication(); - }); + }).then(callbackFunction, errorHandler); }, function(error) @@ -163,86 +145,45 @@ var containsMechanism = function containsMechanism(mechanisms, mech) return false; }; -var doAuthenticate = function doAuthenticate() +var SaslClient = {}; + +SaslClient.authenticate = function(username, password, callbackFunction) { dojo.xhrGet({ - // The URL of the request url: "rest/sasl", - handleAs: "json" + handleAs: "json", + failOk: true }).then(function(data) { - var mechMap = data.mechanisms; - - if (containsMechanism(mechMap, "CRAM-MD5")) - { - saslCramMD5(dojo.byId("username").value, dojo.byId("pass").value); - updateAuthentication(); - } - else if (containsMechanism(mechMap, "PLAIN")) - { - saslPlain(dojo.byId("username").value, dojo.byId("pass").value); - updateAuthentication(); - } - else - { - alert("No supported SASL mechanism offered: " + mechMap); - } - } - ); - - + var mechMap = data.mechanisms; + if (containsMechanism(mechMap, "CRAM-MD5")) + { + saslCramMD5(username, password, "CRAM-MD5", callbackFunction); + } + else if (containsMechanism(mechMap, "CRAM-MD5-HEX")) + { + var hashedPassword = dojox.encoding.digests.MD5(password, dojox.encoding.digests.outputTypes.Hex); + saslCramMD5(username, hashedPassword, "CRAM-MD5-HEX", callbackFunction); + } + else if (containsMechanism(mechMap, "PLAIN")) + { + saslPlain(username, password, callbackFunction); + } + else + { + alert("No supported SASL mechanism offered: " + mechMap); + } + }, errorHandler); }; - -var updateAuthentication = function updateAuthentication() +SaslClient.getUser = function(callbackFunction) { dojo.xhrGet({ - // The URL of the request url: "rest/sasl", - handleAs: "json" - }).then(function(data) - { - if(data.user) - { - dojo.byId("authenticatedUser").innerHTML = data.user; - dojo.style(button.domNode, {display: 'none'}); - dojo.style(usernameSpan, {display: 'block'}); - } - else - { - dojo.style(button.domNode, {display: 'block'}); - dojo.style(usernameSpan, {display: 'none'}); - } - } - ); + handleAs: "json", + failOk: true + }).then(callbackFunction, errorHandler); }; -require(["dijit/form/DropDownButton", "dijit/TooltipDialog", "dijit/form/TextBox", "dojo/_base/xhr", "dojo/dom", "dojo/dom-construct", "dojo/domReady!"], - function(DropDownButton, TooltipDialog, TextBox, xhr, dom, domConstruct){ - var dialog = new TooltipDialog({ - content: - '<strong><label for="username" style="display:inline-block;width:100px;">Username:</label></strong>' + - '<div data-dojo-type="dijit.form.TextBox" id="username"></div><br/>' + - '<strong><label for="pass" style="display:inline-block;width:100px;">Password:</label></strong>' + - '<div data-dojo-type="dijit.form.TextBox" type="password" id="pass"></div><br/>' + - '<button data-dojo-type="dijit.form.Button" data-dojo-props="onClick:doAuthenticate" type="submit">Login</button>' - }); - - button = new DropDownButton({ - label: "Login", - dropDown: dialog - }); - - usernameSpan = domConstruct.create("span", { innerHTML: '<strong>User: </strong> <span id="authenticatedUser"></span><a href="logout">[logout]</a>', - style: { display: "none" }}); - - - var loginDiv = dom.byId("login"); - loginDiv.appendChild(usernameSpan); - loginDiv.appendChild(button.domNode); - - - - - updateAuthentication(); -});
\ No newline at end of file +return SaslClient; +}); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/login.html b/qpid/java/broker-plugins/management-http/src/main/java/resources/login.html new file mode 100644 index 0000000000..aaa2855bd2 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/login.html @@ -0,0 +1,120 @@ +<!DOCTYPE HTML> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You under the Apache License, Version 2.0 + ~ (the "License"); you may not use this file except in compliance with + ~ the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>Qpid Management Login</title> + <link rel="stylesheet" href="dojo/dojo/resources/dojo.css"> + <link rel="stylesheet" href="dojo/dijit/themes/claro/claro.css"> + <link rel="stylesheet" href="css/common.css" media="screen"> + <script> + function getContextPath() + { + var contextPath = "/"; + var documentURL = document.URL; + var managementPageStart = documentURL.lastIndexOf("/"); + var firstSlashPos = documentURL.indexOf("/", documentURL.indexOf("//") + 2); + if (managementPageStart > firstSlashPos) + { + contextPath = documentURL.substring(firstSlashPos, managementPageStart); + } + return contextPath; + } + + var dojoConfig = { + tlmSiblingOfDojo:false, + parseOnLoad:true, + async:true, + baseUrl: getContextPath(), + packages:[ + { name:"dojo", location:"dojo/dojo" }, + { name:"dijit", location:"dojo/dijit" }, + { name:"dojox", location:"dojo/dojox" }, + { name:"qpid", location:"js/qpid" } + ] + }; + + </script> + <script src="dojo/dojo/dojo.js"> + </script> + + <script> + require(["dojo/_base/xhr", + "dojo/parser", + "dijit/form/Form", + "dijit/form/Button", + "dijit/form/TextBox", + "dijit/form/ValidationTextBox", + "dijit/layout/BorderContainer", + "dijit/layout/ContentPane", + "dijit/TitlePane", + "dojox/layout/TableContainer", + "dojox/validate/us", + "dojox/validate/web", + "qpid/common/footer"]); + </script> + +</head> +<body class="claro"> + +<div id="pageLayout" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design: 'headline', gutters: false"> + <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'"> + <div id="header" class="header" style="float: left; width: 300px"></div> + <div id="login" style="float: right"></div> + </div> + <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'"> + <div style="width:350px; margin-left: auto; margin-right: auto;"> + <div data-dojo-type="dijit.form.Form" method="POST" id="loginForm"> + <script type="dojo/on" data-dojo-event="submit" data-dojo-args="e"> + e.preventDefault() + if(this.validate()){ + require(["qpid/authorization/sasl"], function(sasl){ + var redirectIfAuthenticated = function redirectIfAuthenticated(){ + sasl.getUser(function(data){ + if(data.user){ + window.location = "index.html"; + } + }); + }; + + sasl.authenticate(dijit.byId("username").value, dijit.byId("password").value, redirectIfAuthenticated); + }); + } + return false; + </script> + <div data-dojo-type="dijit.TitlePane" data-dojo-props="title:'Login', toggleable: false" > + <div class="dijitDialogPaneContentArea"> + <div data-dojo-type="dojox.layout.TableContainer" data-dojo-props="cols:1,labelWidth:'100',showLabels:true,orientation:'horiz',customClass:'formLabel'"> + <div data-dojo-type="dijit.form.ValidationTextBox" id="username" name="username" data-dojo-props="label:'User name:',required:true, intermediateChanges:true"></div> + <div data-dojo-type="dijit.form.ValidationTextBox" type="password" id="password" name="password" data-dojo-props="label:'Password:',required:true, intermediateChanges:true"></div> + </div> + </div> + <div class="dijitDialogPaneActionBar"> + <button data-dojo-type="dijit.form.Button" type="submit" id="loginButton">Login</button> + </div> + </div> + </div> + </div> + </div> + <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'bottom'"> + <div qpid-type="footer"></div> + </div> +</div> + +</body> +</html>
\ No newline at end of file |