Programming Assignment 3 – Authenticating Administrative Pages

The purpose of this assignment is to introduce you to authentication in website. In particular you will learn about:

  • Spring Security Core plugin for Grails
  • Spring Security UI plugin for Grails
  • How to control access to views

Step 1: Install Plugins.

Spring Security plugins is dependent on several other plugin. Cut and paste into the plugin closure in the BuildConfig.goovy file.

compile ':spring-security-core:2.0-RC4'
compile ":mail:1.0.7"
compile ":jquery-ui:1.10.4"
compile ":famfamfam:1.0.1"
compile ":spring-security-ui:1.0-RC2"

Stop and start your app. All new plugins should install and compile into your app. When you click on the link after the compile you will see a login screen.

Step 2: Set up Spring Security Core.

1. Run S2 Quick Start script.

Open the Grails command prompt by clicking the Grails icon in the tool bar or right click your project and select “Grails Tools” -> “Open Grails Command Prompt” then enter

s2-quickstart cs4760progassign User Role

The script creates 3 domain classes, User.groovy, Role.groovy and UserRole.groovy. Read the tutorial in the Spring Security documentation to learn more:

http://grails-plugins.github.io/grails-spring-security-core/guide/single.html#tutorials

2. Make Role and Users in Bootstrap.groovy

Cut and paste the code below into Bootstrap.groovy init closure.

def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush: true)
def userRole = new Role(authority: 'ROLE_USER').save(flush: true)
 
def testAdmin = new User(username: 'admin', password: 'password')
testAdmin.save(flush: true)
 
def testUser = new User(username: 'user', password: 'password')
testUser.save(flush: true)
 
UserRole.create testAdmin, adminRole, true
UserRole.create testUser, userRole, true

You also have to import the UserRole manually. For some reason the Grails IDE parser does not detect the error.

This makes two roles and two users, one a regular user and the other an admin user.

Run your web app. You’ll see a lot more controllers in the start page. If you click on any controller you will be presented with a login screen. You can login but you’ll still not have authorization to view any of the pages because we have not set up the access.

Step 3: Setup Access to Views.

0. Get Logout

By default Spring Security Core requires post request to logout, but auto generated Logout controller use GET request. For convenience well disable the post only setting. At the bottom of the Config.groovy add the line below.

grails.plugin.springsecurity.logout.postOnly = false

Now during debugging your web app you can logout about clicking the logout controller in the start page.

There are basically two methods for setting up access, either using the Request Mapping or annotating the controller or action. Read the Spring Security documentation about Request Mappings

http://grails-plugins.github.io/grails-spring-security-core/guide/single.html#requestMappings

1. Add Static Rules

Add these two static rules to the grails.plugin.springsecurity.controllerAnnotations.staticRules map at the bottom of the Config.groovy file.

'/home/**': ['permitAll'],
'/book/index': ['permitAll'],
'/author/index': ['permitAll']

Do not forget to add a comma to the end of prior list. Save the file and Grails will automatically without stopping and starting the web app. Now you can view the home and book index views. Try it.

2. Add Annotation to Author Actions

Now you will try annotating the Author controller method. The public should have access only to the index method and admin is required for access to the all the other actions, create, delete, edit, list, save, show, and update. So add the annotation above each of the methods.

@Secured(['ROLE_ADMIN'])

You also need to add the import to the top of the class.

import grails.plugin.springsecurity.annotation.Secured

Stop and start your web app to clear the database. Notice that you can view the home, book, and author index actions without logging in, but you cannot access the author list action without encountering the login screen.

http://localhost:8080/cs4760progassign/author/list/

Login with the admin username and password. You should be able to view the list. In fact you can click on “New Author” button and get to that screen too.

3. Add Annotation to Book class and Index action

We’ll try a different (perhaps easier) annotation technique. You can annotate the whole class. Above the class definition add the secured annotation.

@Secured(['ROLE_ADMIN'])
class BookController {

This will secure all the actions of the Book controller to the admin level. But we want the public to view the index action. So add the ‘permitAll’ secured annotation above the index method.

@Secured(['permitAll'])
def index(){

Stop and start your web app to clear the data base. After you start the browser, notice that you can still get all the index pages, but have to login in to get to the other actions of the Author and Book controller.

Step 4: Spring Security UI

The Spring Security UI plugin provides admin user and role controllers and views, so that the admin can perform common tasks such as adding users and roles. Also Spring Security UI provides views for displaying security information.

1. Accessing User-Role Backend

At the start page you’ll notice that Spring Security UI plugin has added many controllers. At the bottom of the list is the grails.plugin.springsecurity.ui.UserControler. If you click on the link you will be confronted with the login screen. You can login as admin, but that will not give you access to the view.

In Config.groovy, Add to the bottom of the staticRules the entries:

'/user/**': ["ROLE_ADMIN"],
'/role/**': ["ROLE_ADMIN"],
'/registrationCode/**': ["ROLE_ADMIN"],
'/securityInfo/**': ["ROLE_ADMIN"]

Save the file and return to browser and refresh the page. You should see the User Management Search page.

2. Explore User-Role Backend

Read about the Spring Security UI controllers and views in the documentation:

http://grails-plugins.github.io/grails-spring-security-ui/guide/

Explore all the features of the backend. You can access them from the menu bar at the top of the page.

Step 5: Add login/logout to Navbar

In this step you will add login and out links to navbar, also identifier to the person login

1. Read the chapter on Helper Classes in the Spring Security Core plugin documentation:

http://grails-plugins.github.io/grails-spring-security-core/guide/helperClasses.html

You will use the <sec:ifLoggedIn>, <sec:ifNotLoggedIn> and <sec:username> tags in the navbar.

2. Add the following code to _navbar.gsp below the other links for the menu:

<sec:ifLoggedIn><li><a href="#"><sec:username/></a></li></sec:ifLoggedIn>
   <li> 
      <sec:ifLoggedIn><g:link controller="Logout">log out</g:link></sec:ifLoggedIn>
      <sec:ifNotLoggedIn><g:link controller="login" action="auth">Login</g:link></sec:ifNotLoggedIn>
   </li>

3. Refrest or start the app, and try out the new menu items.

Notice that after logging in the user name appears in the navbar. The link could be used to send the user to their profile page.

The <sec:ifLoggedIn>, <sec:ifNotLoggedIn> and < sec:username/> tags are probably accessing session parameters. I’ll speak more about session parameters in a lecture.

Step 6: Study AJAX

AJAX is a technique to create dynamic effect in the view without loading a new page. The basic idea is that a request is sent to the server but the response is returned to the same page instead of loading a new page. In this way only a portion of the page needs to load rather the complete page.

1. Study Javascript

AJAX uses javascript, so you’ll want to study javascript. Good resource is W3 Schools.

http://www.w3schools.com/js/default.asp

Most of the language should be familiar to you. But there are some aspects that you should study.

For the most part, you will be writing functions for event handlers. You should read about javascript functions:

http://www.w3schools.com/js/js_function_definition.asp
http://www.w3schools.com/js/js_function_parameters.asp
http://www.w3schools.com/js/js_function_invocation.asp
http://www.w3schools.com/js/js_function_closures.asp

In browsers, a major purpose of javascript is to manipulate the web page. Javascript’s models the web page as a Document Object Model (DOM). Read the chapters about the DOM.

http://www.w3schools.com/js/js_htmldom.asp
http://www.w3schools.com/js/js_htmldom_methods.asp
http://www.w3schools.com/js/js_htmldom_document.asp
http://www.w3schools.com/js/js_htmldom_elements.asp
http://www.w3schools.com/js/js_htmldom_html.asp
http://www.w3schools.com/js/js_htmldom_css.asp
http://www.w3schools.com/js/js_htmldom_events.asp
http://www.w3schools.com/js/js_htmldom_eventlistener.asp

These tutorials are very short, so will not take long to read. Be sure to try the examples so that you understand each concept.

2. Study JQuery

JQuery is a javascript library that simplifies using javascript. We will be using JQuery, so you will want to study it. A good resource for JQuery is W3 Schools.

http://www.w3schools.com/jquery/default.asp

Be sure to study the introductory chapters about jQuery:

http://www.w3schools.com/jquery/default.asp
http://www.w3schools.com/jquery/jquery_intro.asp
http://www.w3schools.com/jquery/jquery_install.asp – JQuery is installed by default in Grails using the asset plugin, so this tutorial is only good for working with jQuery in isolation.
http://www.w3schools.com/jquery/jquery_syntax.asp
http://www.w3schools.com/jquery/jquery_selectors.asp
http://www.w3schools.com/jquery/jquery_events.asp

Also be sure to study the use of AJAX in jQuery:

http://www.w3schools.com/jquery/jquery_ajax_intro.asp
http://www.w3schools.com/jquery/jquery_ajax_load.asp
http://www.w3schools.com/jquery/jquery_ajax_get_post.asp

After reading the above, you should be prepared to understand the code addition we’ll make to your web app.

Step 7: Make a Simple AJAX Call

Now, we’ll make a very simple ajax code in the home view. We’ll add a link to the home view to show the current date and time.

1. Add the link and result div to the home/index.gsp by adding the code below in the body of view just below the jumbotron.

<!-- Simple Ajax link to show time -->
<g:link action="showTime" elementId="timeLink">Show the time!</g:link>
<div id="time"> time </div>

You should notice that the “Show the time!” link will call the showTime action in the Home controller, so we should make that method.

2. Add the showTime method to the home controller by cutting and pasting the code below.

private static final boolean debugTime = true //flag for debug printing 

def showTime() {
 if(debugTime)println "In showTime"
 render "The time is ${new Date()}"
}

3. Try the link in the browser. It should take you to a new page showing the time.

But, that is not what we want. We would like for the date and time to show on this same page. We need to add some javascript.

4. Make the file showTime.js in grails-app/assets/javascrips/ directory.

Then cut and paste the code below into the file.

console.log("Hello showtime");
$(document).ready( function(){
      $('#timeLink').click(function(){
      console.log("showtime click function");
          $('#time').load(this.href); return false;
       });
});

5. Add the javascript asset to the head of the site layout.

Cut and paste the code below into the /views/layout/site.gsp just below the other asset tag.

<asset:javascript src="application.js"/>

This is the asset pipeline plugin tag that adds the link for javascript. If you inspect the grails-app/asset/javascript/application.js file, you’ll notice that it has the directive:

//= require tree .

which includes all the JavaScript files in the directory.

The asset pipeline does much more especially for the production environment. The link below has a very good video introducing the asset-pipeline plugin.

http://www.bobbywarner.com/2014/02/26/grails-asset-pipeline-plugin/

It is worth watching because you will need to control your assets.

6. Test the code using google chrome or firefox.

The browser that comes with GGTS does not respond to this code even though it should. The GGTS browser still renders in a new page, but with Chrome it will render the date in the div with the time id.

There is more that I want you to learn about Chrome and FireFox. They both have developer tools for debugging web pages and javascript. In Chrome, click on the “hamburger” menu icon (three horizontal bar icon at the upper right) and select developer tools. In FireFox, click on the hamburger menu icon and select developer.

After exposing the developer tools click on the console. You should see the message “Hello showtime.” If not refresh the page and click the “show time” link again. The message is form the console.log method.

There is a lot more features in both of these developer tools that you will use to debug your apps. The “Inspector” or “Inspect Element” tools are good for debugging layout and css. Both Chrome and FireFox allow editing the css in the tool so that you can see the effects in real time.

The “Network” tool will show you request timing. Clicking on a request in the “Network” tool will show you the details of the request.

Step 8: Change AJAX call to trigger on Document Ready Event

Sometimes we want the results of a AJAX to load just after the page has loaded in the browser. The event that the document has loaded is the ready event on the document. Change the javascript in the showtime.js file to:

// Show time - Simple Ajax
 console.log("Hello showtime");
 $(document).ready( function(){
     console.log("In document ready");
     $('#time').load("/cs4760progassign/home/showTime");
     $('#timeLink').click(function(){
     $('#time').load(this.href); return false;
     });
 });

Refresh the page and you’ll see the time div is load with the date and time. You can navigate away from the home page and navigate back, and see that the date and time loads has the page load. You can also use the “Show the time!” link to update the time.

Step 9: Clean Up the Default Start View

1. We want to change the URL mapping for the default start page.

Read about the UrlMapping.groovy configuration file in the Grails documentation.

http://grails.org/doc/latest/guide/theWebLayer.html#urlmappings

Open the conf/UrlMapping.groovy into the editor and notice that the rule

"/"(view:"/index")

maps the base URL to the site index file in /views. We want to route it the Home controller, so replace the line with

"/"(controller:"home")

2. After editing the URL mapping try pointing your browser to

/cs4760progassign/

The index action for the Home controller should show.

3. We would like for admin to still have access to old start page that links all the controller.

There are several steps.

a. Rename the file /views/index.gsp to /views/controllerlist.gsp
b. In UrlMapping.groovy, add the static rule

"/controllerlist"(view:"controllerlist")

c. Give ADMIN_ROLE access to the url “/controllerlist” by adding the following line to staticRules closure in the Config.groovy file.

‘/controllerlist’: [“ROLE_ADMIN”]

Now if you point the browser to “/cs4760progassign/controllerlist” you’ll have to log in as admin. Then you will be able to view the list of controllers.

Step 10: Make AJAX Recent Book

On the Book Store home page we went the most recently published book to appear below the time. The home page should look something like

Book Store
Show the time!
The time is …..

Most Recent Book
The Stand by Stephen King

You are on your own coding this AJAX call, but I can give you some hints. Use the Domain class “last” method.

Note that AJAX calls in this assignment are only for example. You would generally not use AJAX calls like these to generate dynamic content. Rather you would have the controller send the view a map as we did in the prior assignment. There is one case when you might have to use AJAX calls for dynamic content in the view. That is when the view should work both online and offline (meaning with or without an internet connection). In that case, the view must identify if there is an internet connect or not. If there is not an internet connection then generally the view should get the dynamic content from local storage, and if there is an internet connection then the view should get the dynamic content from an AJAX call similar to the ones in this assignment.

Step 11: Make the Screen Shot and Email Me

After creating the AJAX call for the most recent book, make two screen shows, one of your home/index.gsp and the other of the javascript file.

Email me the screen shots. The subject of the email should be

“cs4760 Programming Assignment 3 Proof”

Congratulations, you authorized your website and made your own AJAX call.