{"id":272,"date":"2013-06-25T15:30:43","date_gmt":"2013-06-25T19:30:43","guid":{"rendered":"http:\/\/localhost\/cs4760\/2014\/?page_id=272"},"modified":"2026-01-26T15:43:43","modified_gmt":"2026-01-26T20:43:43","slug":"programming-assignment-3-authenticating","status":"publish","type":"page","link":"https:\/\/cs4760.csl.mtu.edu\/2026\/assignments\/cs4760-assignments\/programming-assignments\/programming-assignment-3-authenticating\/","title":{"rendered":"Programming Assignment 3 \u2013 Authenticating Administrative Pages"},"content":{"rendered":"\n<p>The purpose of this assignment is to introduce you to authentication in websites. In particular, you will learn about:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Spring Security Core plugin for Grails<\/li>\n\n\n\n<li>Spring Security UI plugin for Grails<\/li>\n\n\n\n<li>How to control access to views<\/li>\n\n\n\n<li>Bonus: Learn how to make AJAX calls<\/li>\n<\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">Step 1: Install Spring Security Plugins<\/h1>\n\n\n\n<p>We will use the Spring Security Core plugin with an additional plugin, the Spring Security UI plugin. The Spring Security Core authenticates users and control access to pages. The Spring Security UI provides convenient UI&nbsp; for controlling access and users. It also uses the mail plugin during the registration and reset forgotten passwords. The documentation for the plugins are at:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/apache.github.io\/grails-spring-security\/latest\/core-plugin\/guide\/\">https:\/\/apache.github.io\/grails-spring-security\/latest\/core-plugin\/guide\/<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/apache.github.io\/grails-spring-security\/latest\/ui-plugin\/guide\/\">https:\/\/apache.github.io\/grails-spring-security\/latest\/ui-plugin\/guide\/<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/grails-plugins\/grails-mail\">https:\/\/github.com\/grails-plugins\/grails-mail<\/a><\/li>\n<\/ul>\n\n\n\n<p>To install plugins, all you need to do is to list them in build.gradle file (found at the root of the project files). Near the bottom of the build.gradle file, you should see a long list of <strong>dependencies<\/strong>. Cut and paste into this dependencies&nbsp;list the declarations below:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"groovy\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">dependencies {\n    ...\n    \/\/ Add for Spring Security\n    \/\/ implementation \"org.grails.plugins:spring-security-core:5.1.0\" \/\/ Do not need. Spring Security UI dependencies will add\n    implementation 'org.grails.plugins:spring-security-ui:4.0.0-RC1'\n    \/\/ implementation 'org.grails.plugins:mail:2.0.0' \/\/ Does not work using Java 11. Also don't have to use.\n}<\/pre>\n\n\n\n<p>If you stop and start your app now, you will not get what you expect. The browser will be redirected to the login screen (with bad\/broken styling). We need to setup Spring Security Core.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Step 2: Setup Spring Security Core.<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">1. Run S2 Quick Start script.<\/h2>\n\n\n\n<p>Run the Grails command at the project root directory using a Bash terminal<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">.\/grailsw s2-quickstart cs4760progassign User Role<\/pre>\n\n\n\n<p>The script creates 3 domain classes, User.groovy, Role.groovy and UserRole.groovy. It also creates a application.groovy file in grails-app\/conf\/ directory. You may need to reload the project files into IntelliJ IDEA by clicking the &#8220;refresh&#8221; arrows in the toolbar. Read the tutorial in the Spring Security documentation to learn more:<\/p>\n\n\n\n<p><a href=\"https:\/\/apache.github.io\/grails-spring-security\/latest\/core-plugin\/guide\/#tutorials\">https:\/\/apache.github.io\/grails-spring-security\/latest\/core-plugin\/guide\/#tutorials<\/a><\/p>\n\n\n\n<p>If you read the first part of the tutorial, you notice that we should add<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"groovy\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">grails.plugin.springsecurity.logout.postOnly = false<\/pre>\n\n\n\n<p>to the bottom of the conf\/application.groovy file. This makes logout easy. During debugging your web app, you can logout by clicking the logout controller in the control list page.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Make Role and Users in Bootstrap.groovy<\/h2>\n\n\n\n<p>We can add some users and roles to the Bootstrap.groovy file.&nbsp;Cut and paste the code below into init\/Bootstrap.groovy init closure.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"groovy\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">package cs4760progassign\n\nimport grails.gorm.transactions.Transactional\n\nclass BootStrap {\n\n    @Transactional\n    void addUsers() {\n        \/\/ Add for creating Roles and Users\n        def adminRole= new Role(authority: 'ROLE_ADMIN').save(flush: true)\n        def userRole = new Role(authority: 'ROLE_USER').save(flush: true)\n\n        def testAdmin = new User(username: 'admin', password: 'password')\n        testAdmin.save(flush: true)\n\n        def testUser = new User(username: 'user', password: 'password')\n        testUser.save(flush: true)\n\n        UserRole.create testAdmin, adminRole, true\n        UserRole.create testUser, userRole, true\n        UserRole.withSession {\n            it.flush()\n            it.clear()\n        }\n    }\n\n    def init = { servletContext ->\n        addUsers()\n        ...\n    }\n\n    def destroy = {\n    }\n\n}<\/pre>\n\n\n\n<p>If you do not have the package specification, you may have to import the User, Role and UserRole,&nbsp;click on the offending class name, then hit alt-enter, finally&nbsp;select import. Also be sure to import <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">grails.gorm.transactions.Transactional<\/code> and to annotate the  <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">addUsers <\/code>method with <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">@Transactonal<\/code>. Do not forget to call <code data-enlighter-language=\"groovy\" class=\"EnlighterJSRAW\">addUsers <\/code>in the <code data-enlighter-language=\"groovy\" class=\"EnlighterJSRAW\">init <\/code>method. <\/p>\n\n\n\n<p>The code makes two roles and two users, one a regular user and the other an admin user.<\/p>\n\n\n\n<p>Rerun your web app. If you navigate away from the home page, you&#8217;ll be prompted with a log in screen. You can log in and see the home page, but you cannot navigate to any other pages because neither Admin or User roles are authorize to see any pages yet. Spring Security set pessimistic locking by default:<\/p>\n\n\n\n<p><a href=\"https:\/\/apache.github.io\/grails-spring-security\/latest\/core-plugin\/guide\/#pessimistic-lockdown\">https:\/\/apache.github.io\/grails-spring-security\/latest\/core-plugin\/guide\/#pessimistic-lockdown<\/a><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Step 3: Setup Access to Views<\/h1>\n\n\n\n<p>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<\/p>\n\n\n\n<p><a href=\"https:\/\/apache.github.io\/grails-spring-security\/latest\/core-plugin\/guide\/#requestMappings\">https:\/\/apache.github.io\/grails-spring-security\/latest\/core-plugin\/guide\/#requestMappings<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Add Static Rules<\/h2>\n\n\n\n<p>We use static mapping for the public views.<\/p>\n\n\n\n<p><a href=\"https:\/\/apache.github.io\/grails-spring-security\/latest\/core-plugin\/guide\/#configGroovyMap\">https:\/\/apache.github.io\/grails-spring-security\/latest\/core-plugin\/guide\/#configGroovyMap<\/a><\/p>\n\n\n\n<p>Add these static rules to the grails.plugin.springsecurity.controllerAnnotations.staticRules map at the bottom of the conf\/application.groovy file.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"groovy\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">grails.plugin.springsecurity.controllerAnnotations.staticRules = [\n    ...\n    [pattern: '\/books\/**',       access: ['permitAll']],\n    [pattern: '\/authors\/**',     access: ['permitAll']],\n\n    [pattern: '\/controllerList\/**', access: ['ROLE_ADMIN']],\n    [pattern: '\/author\/**',         access: ['ROLE_ADMIN']],\n]<\/pre>\n\n\n\n<p>Do not forget to add a comma to the end of the prior list. But I have noticed that groovy parser does not mind if the last item in a list has a comma, so I leave it with a comma at the end, making it easy to add more rules.<\/p>\n\n\n\n<p>The first two rules grants&nbsp;public to access to all of the books and authors views. The last two rule restrict access to the controllerList and author views to admin users.<\/p>\n\n\n\n<p>Rerun the grails app.  Working through the programming assignment this year, I noticed a new error after adding new static rules to the application.groovy. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><span style=\"background-color:rgba(0, 0, 0, 0);color:#a3001f\" class=\"has-inline-color\">FAILURE: Build failed with an exception.\n\nWhat went wrong:\nExecution failed for task ':findMainClass'.\nUnable to find a single main class from the following candidates [application, cs4760progassign.Application]<\/span><\/pre>\n\n\n\n<p>To fix the this error you need to rebuild the project from scratch. To do this, enter<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">.\/gradlew clean<\/pre>\n\n\n\n<p>Then run the app. It should now build and run. <\/p>\n\n\n\n<p>Open the app in your browser. Now you can view the home and books index views. To view the controller list you&#8217;ll need to login as admin. You still can not access the book views.<\/p>\n\n\n\n<p>If you try access a page that you do not have authorization to view Spring Security will confront you with a login page. After logging in, Spring Security should redirect you to the page that you tried to access. This does not happen all the time (I&#8217;m not sure why) and the browser remains on the login page. If this happens, you can navigate to page using the browser&#8217;s back arrow. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Add Annotation to BookController<\/h2>\n\n\n\n<p>Read about annotating controller actions at<\/p>\n\n\n\n<p><a href=\"https:\/\/apache.github.io\/grails-spring-security\/latest\/core-plugin\/guide\/#securedAnnotations\">https:\/\/apache.github.io\/grails-spring-security\/latest\/core-plugin\/guide\/#securedAnnotations<\/a><\/p>\n\n\n\n<p>Now, you try annotating the Book&nbsp;controller methods. Add the annotation just above the class definition.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"groovy\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Secured(['ROLE_ADMIN'])\nclass BookController {\n...\n}<\/pre>\n\n\n\n<p>You also need to add the import to the top of the class.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"groovy\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import grails.plugin.springsecurity.annotation.Secured<\/pre>\n\n\n\n<p>Stop and start your web app. Notice that you can view the the home page, Books and Authors &nbsp;index actions without logging in, but you cannot access the Author or Book&nbsp;actions without encountering the login screen.<\/p>\n\n\n\n<p>Generally, you do not want to mix the two techniques. I prefer to use the static rules instead of the annotation for two reasons. First, you can see all the rules at once in application.groovy. Second, you can control access to code you did not write, for example a plugin, without modify the plugin code.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Step 4: Spring Security UI<\/h1>\n\n\n\n<p>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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Accessing User-Role Backend<\/h2>\n\n\n\n<p>At the start page you&#8217;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.<\/p>\n\n\n\n<p>In the conf\/applictaion.groovy, add to the bottom of the staticRules the entries:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"groovy\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[pattern: '\/user\/**',             access: ['ROLE_ADMIN']],\n[pattern: '\/role\/**',             access: ['ROLE_ADMIN']],\n[pattern: '\/registrationCode\/**', access: ['ROLE_ADMIN']],\n[pattern: '\/securityInfo\/**',     access: ['ROLE_ADMIN']],\n[pattern: '\/logout\/**',           access: ['permitAll']],<\/pre>\n\n\n\n<p>We also add the finally rule to let anyone logout.<\/p>\n\n\n\n<p>You will need to restart the grails app. Login as admin, you should see the User Management Search page.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Explore User-Role Backend<\/h2>\n\n\n\n<p>Read about the Spring Security UI controllers and views in the documentation:<\/p>\n\n\n\n<p><a href=\"https:\/\/apache.github.io\/grails-spring-security\/latest\/ui-plugin\/guide\">https:\/\/apache.github.io\/grails-spring-security\/latest\/ui-plugin\/guide<\/a><\/p>\n\n\n\n<p>Spring Security UI is a good tool for learning about Spring Security, so explore all the features of the backend. You can access them from the menu bar at the top of the page.<\/p>\n\n\n\n<p>Spring Security UI has many configurations and techniques to customize. You should reread the documentation, especially the &#8220;Customization&#8221; section if you use it for your team project application.    <\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Step 5: Add login\/logout to Navbar<\/h1>\n\n\n\n<p>In this step you will add login and out links to the navbar. You can also have the navbar identifiy the person logged in.<\/p>\n\n\n\n<p>Read the chapter on Helper Classes in the Spring Security Core plugin documentation. In particular read about the Security Tag Library:<\/p>\n\n\n\n<p><a href=\"https:\/\/apache.github.io\/grails-spring-security\/latest\/core-plugin\/guide\/#securityTagLib\">https:\/\/apache.github.io\/grails-spring-security\/latest\/core-plugin\/guide\/#securityTagLib<\/a><\/p>\n\n\n\n<p>You will use the &lt;sec:ifLoggedIn&gt;, &lt;sec:ifNotLoggedIn&gt; and &lt;sec:username&gt; tags in the navbar.<\/p>\n\n\n\n<p>Add the following code to _navbar.gsp below the other links for the menu:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"html\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;sec:ifLoggedIn>\n     &lt;li class=\"nav-item\">\n         &lt;a class=\"nav-link\" href=\"#\">&lt;sec:username\/>&lt;\/a>\n     &lt;\/li>\n&lt;\/sec:ifLoggedIn>\n&lt;li class=\"nav-item\">\n     &lt;sec:ifLoggedIn>&lt;g:link class=\"nav-link\" controller=\"Logout\">log out&lt;\/g:link>&lt;\/sec:ifLoggedIn>\n     &lt;sec:ifNotLoggedIn>&lt;g:link class=\"nav-link\" controller=\"login\" action=\"auth\">Login&lt;\/g:link>&lt;\/sec:ifNotLoggedIn>\n&lt;\/li><\/pre>\n\n\n\n<p>Restart the app, and try out the new menu items.<\/p>\n\n\n\n<p>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.<\/p>\n\n\n\n<p>The <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">&lt;sec:ifLoggedIn&gt;<\/code>, <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">&lt;sec:ifNotLoggedIn&gt;<\/code> and <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">&lt; sec:username\/&gt;<\/code> tags are accessing session parameters. I&#8217;ll speak more about session parameters in a lecture.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Step 6: Study AJAX<\/h1>\n\n\n\n<p>AJAX is a technique to create dynamic effects in a 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 than the complete page.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Study JavaScript<\/h2>\n\n\n\n<p>AJAX uses JavaScript, so you&#8217;ll want to study JavaScript. A good resource is W3 Schools.<\/p>\n\n\n\n<p><a href=\"http:\/\/www.w3schools.com\/js\/default.asp\">http:\/\/www.w3schools.com\/js\/default.asp<\/a><\/p>\n\n\n\n<p>An more complete resource is at the Mozilla Developer Network.<\/p>\n\n\n\n<p><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\">https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript<\/a><\/p>\n\n\n\n<p>Most of the language should be familiar to you. But there are some aspects that you should study.<\/p>\n\n\n\n<p>For the most part, you will be writing functions for event handlers. You should read about javascript functions:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.w3schools.com\/js\/js_functions.asp\">https:\/\/www.w3schools.com\/js\/js_functions.asp<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.w3schools.com\/js\/js_events.asp\">https:\/\/www.w3schools.com\/js\/js_events.asp<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.w3schools.com\/js\/js_arrow_function.asp\">https:\/\/www.w3schools.com\/js\/js_arrow_function.asp<\/a><\/li>\n<\/ul>\n\n\n\n<p>A&nbsp;major purpose of javascript is to manipulate the web page. Javascript&#8217;s models the web page as a Document Object Model (DOM). Read the chapters about the DOM.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"http:\/\/www.w3schools.com\/js\/js_htmldom.asp\">http:\/\/www.w3schools.com\/js\/js_htmldom.asp<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/www.w3schools.com\/js\/js_htmldom_methods.asp\">http:\/\/www.w3schools.com\/js\/js_htmldom_methods.asp<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/www.w3schools.com\/js\/js_htmldom_document.asp\">http:\/\/www.w3schools.com\/js\/js_htmldom_document.asp<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/www.w3schools.com\/js\/js_htmldom_elements.asp\">http:\/\/www.w3schools.com\/js\/js_htmldom_elements.asp<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/www.w3schools.com\/js\/js_htmldom_html.asp\">http:\/\/www.w3schools.com\/js\/js_htmldom_html.asp<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/www.w3schools.com\/js\/js_htmldom_css.asp\">http:\/\/www.w3schools.com\/js\/js_htmldom_css.asp<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/www.w3schools.com\/js\/js_htmldom_events.asp\">http:\/\/www.w3schools.com\/js\/js_htmldom_events.asp<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/www.w3schools.com\/js\/js_htmldom_eventlistener.asp\">http:\/\/www.w3schools.com\/js\/js_htmldom_eventlistener.asp<\/a><\/li>\n<\/ul>\n\n\n\n<p>These tutorials are very short, so they will not take long to read. Be sure to try the examples so that you understand each concept.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Study JQuery<\/h2>\n\n\n\n<p>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.<\/p>\n\n\n\n<p><a href=\"http:\/\/www.w3schools.com\/jquery\/default.asp\">http:\/\/www.w3schools.com\/jquery\/default.asp<\/a><\/p>\n\n\n\n<p>Be sure to study the introductory chapters about jQuery:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"http:\/\/www.w3schools.com\/jquery\/default.asp\">http:\/\/www.w3schools.com\/jquery\/default.asp<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/www.w3schools.com\/jquery\/jquery_intro.asp\">http:\/\/www.w3schools.com\/jquery\/jquery_intro.asp<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/www.w3schools.com\/jquery\/jquery_syntax.asp\">http:\/\/www.w3schools.com\/jquery\/jquery_syntax.asp<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/www.w3schools.com\/jquery\/jquery_selectors.asp\">http:\/\/www.w3schools.com\/jquery\/jquery_selectors.asp<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/www.w3schools.com\/jquery\/jquery_events.asp\">http:\/\/www.w3schools.com\/jquery\/jquery_events.asp<\/a><\/li>\n<\/ul>\n\n\n\n<p>Also be sure to study the use of AJAX in jQuery:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"http:\/\/www.w3schools.com\/jquery\/jquery_ajax_intro.asp\">http:\/\/www.w3schools.com\/jquery\/jquery_ajax_intro.asp<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/www.w3schools.com\/jquery\/jquery_ajax_load.asp\">http:\/\/www.w3schools.com\/jquery\/jquery_ajax_load.asp<\/a><\/li>\n\n\n\n<li><a href=\"http:\/\/www.w3schools.com\/jquery\/jquery_ajax_get_post.asp\">http:\/\/www.w3schools.com\/jquery\/jquery_ajax_get_post.asp<\/a><\/li>\n<\/ul>\n\n\n\n<p>More resources are available at the jQuery Learning Center.<\/p>\n\n\n\n<p><a href=\"https:\/\/learn.jquery.com\/\">https:\/\/learn.jquery.com\/<\/a> <\/p>\n\n\n\n<p>After reading the above, you should be prepared to understand the code that we&#8217;ll add to our web app.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Step 7: Make a Simple AJAX Call<\/h1>\n\n\n\n<p>Now, we&#8217;ll make a very simple ajax code in the home view. We&#8217;ll add a link to the home view to show the current date and time.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Edit index.gsp<\/h2>\n\n\n\n<p>In the views\/index.gsp file, add the link and result div to the home\/index.gsp by adding the code below in the body of the view just below the&nbsp;jumbotron div.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"html\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;!-- Simple Ajax link to show time -->\n&lt;g:link controller=\"home\" action=\"showTime\" elementId=\"timeLink\">Show the time!&lt;\/g:link>\n&lt;div id=\"time\"> time &lt;\/div><\/pre>\n\n\n\n<p>You should notice that the &#8220;Show the time!&#8221; link will call the showTime action in the Home controller, so we should make that controller and action.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Add the Server Code<\/h2>\n\n\n\n<p>We need place to run the server code. Typically, we would use the controller for the view, but currently the home page does not have a controller associated with it. Note that the g:link already specifies a Home controller. Make a new controller call it Home. After Grails has generated the controller, add a showTime method to the home controller by cutting and pasting the code below.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"groovy\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">private static final boolean debugTime = true \/\/flag for debug printing \n\ndef showTime() {\n if(debugTime)println \"In showTime\"\n render \"The time is ${new Date()}\"\n}<\/pre>\n\n\n\n<p>You also need to grant the public access to home controller. In application.groovy add the following static rules:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"groovy\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[pattern: '\/home\/**',              access: ['permitAll']],<\/pre>\n\n\n\n<p>You&#8217;ll have to clean the project before rerunning Grails. Rerun the Grail and try the link in the browser. It should take you to a new page showing the time.<\/p>\n\n\n\n<p>But, that is not what we want. We would like for the date and time to show on the same home  page. We need to add some JavaScript.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Add JavaScript<\/h2>\n\n\n\n<p>In grails-app\/assets\/javascrips\/ directory, make showTime.js file.&nbsp;Then cut and paste the code below into the file.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">console.log(\"Hello showtime\");\n$(document).ready( function(){\n      $('#timeLink').click(function(){\n         console.log(\"showtime click function\");\n         $('#time').load(this.href); \n         return false;\n      });\n});\n<\/pre>\n\n\n\n<p>Note that you need the &#8220;return false&#8221; to prevent the normal behavior, the link navigating to a new page. <\/p>\n\n\n\n<p>You might wonder how the showTime.js file is added to the page<\/p>\n\n\n\n<p>In&nbsp;the \/views\/layout\/site.gsp, the other asset tag at the bottom of the page tells asset-pipeline&nbsp;to source the application.js.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"html\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;asset:javascript src=\"application.js\"\/><\/pre>\n\n\n\n<p>Inspect the grails-app\/asset\/javascript\/application.js file, add above &#8220;\/\/= require self&#8221; the directive:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/= require_tree .\n\/\/= require_self<\/pre>\n\n\n\n<p>which will include all the JavaScript files in&nbsp;the directory.<\/p>\n\n\n\n<p>The asset pipeline\u00a0does much more, especially in the production environment. The plugin code is at <\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/wondrify\/asset-pipeline\">https:\/\/github.com\/wondrify\/asset-pipeline<\/a><\/p>\n\n\n\n<p>and the documentation is at <\/p>\n\n\n\n<p><a href=\"https:\/\/wondrify.github.io\/asset-pipeline\">https:\/\/wondrify.github.io\/asset-pipeline<\/a><\/p>\n\n\n\n<p>It is worth reading because you will need to control your assets.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Test the Code<\/h2>\n\n\n\n<p>Run the app. You may need to make a hard refresh of the page by hold shift andclicking the refresh button.  <\/p>\n\n\n\n<p>I want you to learn about Chrome and FireFox developer tools. They both have developer tools for debugging web pages and JavaScript. In Chrome and Firefox, right click on the page and select inspect. In the panel that opens, select console tab.<\/p>\n\n\n\n<p>You should see the message &#8220;Hello showtime.&#8221; If not refresh the page and click the &#8220;show time&#8221; link again. The message is form the console.log method.<\/p>\n\n\n\n<p>There are a lot more features in both of these developer tools that you will use to debug your apps. The &#8220;Inspector&#8221; or &#8220;Inspect Element&#8221; 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.<\/p>\n\n\n\n<p>The &#8220;Network&#8221; tool will show you request timing. Clicking on a request in the &#8220;Network&#8221; tool will show you the details of the request.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Step 8: Change AJAX call to trigger on Document Ready Event<\/h1>\n\n\n\n<p>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:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ Show time - Simple Ajax\n console.log(\"Hello showtime\");\n $(document).ready( function(){\n     console.log(\"In document ready\");\n     $('#time').load(\"\/cs4760progassign\/home\/showTime\");\n     $('#timeLink').click(function(){\n     $('#time').load(this.href); \n     return false;\n     });\n });<\/pre>\n\n\n\n<p>Refresh the page and you&#8217;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 new date and time. You can also use the &#8220;Show the time!&#8221; link to update the time.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Step 9: Make AJAX Recent Book<\/h1>\n\n\n\n<p>On the Book Store home page we want the most recently published book to appear below the time. The home page should look something like<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Book Store\nShow the time!\nThe time is \u2026..\n\nMost Recent Book\nThe Stand by Stephen King\n<\/pre>\n\n\n\n<p>You are on your own coding this AJAX call, but I can give you some hints. Use the &#8220;first&#8221; or &#8220;last&#8221; method on the list that you get from the Book domain.<\/p>\n\n\n\n<p>Note that the AJAX calls in this assignment are only for example. You would generally not use AJAX calls like these to generate simple dynamic content. Rather you would have the controller send the view a model as we did in the prior assignment.<\/p>\n\n\n\n<p>You should use an AJAX call when the user updates data in the view. Rather than redrawing the entire page, you would have the AJAX call update the effected portion of the view.<\/p>\n\n\n\n<p>There another case for using 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.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Step 10: Make Screen Shots and Submit<\/h1>\n\n\n\n<p>After creating the AJAX call for the most recent book, make two screen shows, one of your index.gsp and the other of the javascript file.<\/p>\n\n\n\n<p>Submit the screen shots in canvas for the &#8220;Assignment Programming Assignment 3 \u2013 Authenticating Administrative Pages&#8221;<\/p>\n\n\n\n<p>Congratulations, you have secured your website and made an AJAX call.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The purpose of this assignment is to introduce you to authentication in websites. In particular, you will learn about: Step 1: Install Spring Security Plugins We will use the Spring Security Core plugin with an additional plugin, the Spring Security UI plugin. The Spring Security Core authenticates users and control access to pages. The Spring [&hellip;]<\/p>\n","protected":false},"author":62,"featured_media":0,"parent":77,"menu_order":3,"comment_status":"closed","ping_status":"closed","template":"page-templates\/front-page.php","meta":{"footnotes":""},"class_list":["post-272","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/cs4760.csl.mtu.edu\/2026\/wp-json\/wp\/v2\/pages\/272","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cs4760.csl.mtu.edu\/2026\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/cs4760.csl.mtu.edu\/2026\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/cs4760.csl.mtu.edu\/2026\/wp-json\/wp\/v2\/users\/62"}],"replies":[{"embeddable":true,"href":"https:\/\/cs4760.csl.mtu.edu\/2026\/wp-json\/wp\/v2\/comments?post=272"}],"version-history":[{"count":48,"href":"https:\/\/cs4760.csl.mtu.edu\/2026\/wp-json\/wp\/v2\/pages\/272\/revisions"}],"predecessor-version":[{"id":4302,"href":"https:\/\/cs4760.csl.mtu.edu\/2026\/wp-json\/wp\/v2\/pages\/272\/revisions\/4302"}],"up":[{"embeddable":true,"href":"https:\/\/cs4760.csl.mtu.edu\/2026\/wp-json\/wp\/v2\/pages\/77"}],"wp:attachment":[{"href":"https:\/\/cs4760.csl.mtu.edu\/2026\/wp-json\/wp\/v2\/media?parent=272"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}