Example: OAuth2 Implicit Flow using Membrane
Membrane can act as an OAuth2 authorization server for usage with an OAuth2 compatible client.
Figure1:
Running the Example
In this example we will use Membrane as an authorization server that can authenticate users through a login dialog and a client that communicates with this authentication server on behalf of the user to securely access an unprotected resource.
To run the example go to the $MEMBRANE_HOME/examples/oauth2/implicit folder in the Membrane Service Proxy distribution. Complete the following steps:
- Run the service-proxy.bat/.sh in the authorization_server subfolder.
- Run the service-proxy.bat/.sh in the webserver subfolder.
- Navigate to http://localhost:2000 in your browser to start the login procedure.
- Log in with john as username and password as password.
- Give consent for sharing information by clicking on accept.
- Observe that you get redirected automatically to the resource.
Details
The following part describes the example in detail.
Authorization Server
For a comprehensive description of the authorization server please follow to the OAuth2 authorization code example and there to the Details heading.
Webserver
The webserver's only task is to host the JavaScript client. It can be replaced by any other standard hosting software e.g Tomcat.
Take a look at the proxies.xml.
<serviceProxy name="Membrane Resource service" port="2000"> <path>/oauth2callback</path> <groovy> Response.ok(new File("C:\\Users\\Predic8\\git\\service-proxy-Master\\distribution\\conf\\JavaScriptClient.html").text).build() </groovy> </serviceProxy> <serviceProxy name="Membrane Resource service" port="2000"> <groovy> Response.ok(new File("C:\\Users\\Predic8\\git\\service-proxy-Master\\distribution\\conf\\JavaScriptClient.html").text).build() </groovy> </serviceProxy>
The webserver provides 2 endpoints that serve the same file. The file is a sample implementation of an OAuth2 client in JavaScript. It is not ready for production usage. The webserver is available on port 2000. It serves the JavaScript client when called directly or through the OAuth2 callback.
JavaScript client
The JavaScript client implements a typical basic user agent OAuth2 client.
<script> var redirect = function(){ window.location = 'http://localhost:7000/oauth2/auth?response_type=token&client_id=' + encodeURIComponent('abc') + '&redirect_uri=' + encodeURIComponent('http://localhost:2000/oauth2callback') + '&scope=' + 'profile'; }; var getParams = function(){ var querysRaw = window.location.search.substring(1).split('&'); var result = new Object(); for(var i = 0; i < querysRaw.length;i++){ var pair = querysRaw[i].split("="); result[pair[0]] = pair[1]; } sessionStorage.setItem("auth",result.token_type + " " + result.access_token) return result; }; var validateAccessToken = function(auth){ var xmlhttp = new XMLHttpRequest(); xmlhttp.open('GET',"http://localhost:7000/oauth2/userinfo",true); xmlhttp.setRequestHeader("Authorization", auth); xmlhttp.send(null); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4) { if ( xmlhttp.status == 200) { alert("Validation successful.") } else { sessionStorage.clear(); redirect(); } } } } var accessToken = sessionStorage.getItem("auth"); if(accessToken){ validateAccessToken(accessToken); } else if (window.location.pathname == "/oauth2callback") { getParams(); validateAccessToken( sessionStorage.getItem("auth")); } else{ redirect(); } </script>
The JavaScript client starts the OAuth2 implicit flow when there is no access token in the browsers session. It also processes oauth2callback redirects from the authorization server. When the flow is finished the access token is saved. On following requests the access token is reused for validation.
Help needed?
Do you need any help for this scenario? Then contact us using the Membrane Google Group or send an email to membrane@predic8.com.