Ibrahim Mohamed
Ibrahim Mohamed

Reputation: 75

Spring security not allowing angularjs to Run

I have a todo spring boot app works 100% without spring security ,but if i use spring security angularjs will not work any more i use thymeleaf for pages but this page i use HTML with Angular without thymeleaf but angular actions will not work i am sure that the problem is with spring security HTML PAGE :

<!DOCTYPE html>
<html ng-app="taskManagerApp" >
<head>
    <meta charset="utf-8"/>
    <!--IE Compatibility Meta-->
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <!--first Mobile Meta-->
    <meta name="viewport" content="width=device-width, initial-scale=1"/>

    <title>Tasks</title>



    <!--css fontawesome jb-->
    <link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'/>



    <!--My Css File-->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css"/>


    <link rel="stylesheet" href="/css/task.css"/>

    <link rel="stylesheet"  href="/css/animate.css"/>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"/>



    <link rel="stylesheet" href="/css/style.css"/>

    <!--if IT IE 9-->
    <script data-require="angular.js@*" data-semver="1.3.0-beta.14"
            src="http://code.angularjs.org/1.3.0-beta.14/angular.js"></script>
    <script data-require="angular-animate@*" data-semver="1.3.0-beta.14"
            src="http://code.angularjs.org/1.3.0-beta.14/angular-animate.js"></script>

    <script type="text/javascript" src="/js/app.js"></script>

    <script src="/js/html5shiv.min.js"></script>
    <script src="/js/respond.min.js"></script>
    <script src="/js/jquery-1.11.1.min.js"></script>
    <script src="/js/jquery.nicescroll.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="/js/main-p.js"></script>
    <script src="/js/plugin.js"></script>

    <!--endif-->


</head>
<body>

<!--==============Start Menu==========-->

<div class="row">

    <nav class="navbar navbar-inverse sidebar  col-sm-6 col-md-2" role="navigation">
        <div class="container-fluid">
            <!-- Brand and toggle get grouped for better mobile display -->
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse"
                        data-target="#bs-sidebar-navbar-collapse-1">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="#">Our logo</a>
            </div>
            <!-- Collect the nav links, forms, and other content for toggling -->
            <div class="collapse navbar-collapse" id="bs-sidebar-navbar-collapse-1">
                <ul class="nav navbar-nav">
                    <li class="active"><a href="/main">&#35; Activity<span style="font-size:16px;"
                                                                                 class="pull-right hidden-xs showopacity glyphicon glyphicon-home"></span></a>
                    </li>

                    <li><a href="/chat">Chat<span style="font-size:16px;"
                                                        class="pull-right hidden-xs showopacity fa fa-comments"></span></a>
                    </li>
                    <li><a href="/task">Tasks<span style="font-size:16px;"
                                                          class="pull-right hidden-xs showopacity fa fa-bolt"></span></a>
                    </li>
                    <li><a href="/file">Files<span style="font-size:16px;"
                                                         class="pull-right hidden-xs showopacity fa fa-paperclip"></span></a>
                    </li>
                    <li><a href="/calender">Calender<span style="font-size:16px;"
                                                                class="pull-right hidden-xs showopacity fa fa-calculator"></span></a>
                    </li>
                    <li><a href="/search">Search<span style="font-size:16px;"
                                                            class="pull-right hidden-xs showopacity fa fa-search"></span></a>
                    </li>
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown">Settings <span
                                class="caret"></span><span style="font-size:16px;"
                                                           class="pull-right hidden-xs showopacity glyphicon glyphicon-cog"></span></a>
                        <ul class="dropdown-menu forAnimate" role="menu">
                            <li><a href="#">Action</a></li>
                            <li><a href="#">Another action</a></li>
                            <li><a href="#">Something else here</a></li>
                            <li class="divider"></li>
                            <li><a href="#">Separated link</a></li>
                            <li class="divider"></li>
                            <li><a href="#">One more separated link</a></li>
                        </ul>
                    </li>
                </ul>
            </div>
        </div>
    </nav>

    <!--==========End Section Menu=========-->


    <!--==========Start Section Project=========-->

    <div class="right-side col-xs-11 col-sm-11 col-md-10">
        <!--==========Start Navbar=========-->
        <div class="container">
            <div class="row">
                <div class="col-md-12">
                    <div class="navbar-wrapper">
                        <div class="container">
                            <div class="navbar navbar-inverse navbar-static-top" role="navigation">
                                <div class="container">
                                    <div class="navbar-header">
                                        <button type="button" class="navbar-toggle" data-toggle="collapse"
                                                data-target=".navbar-collapse">
                                            <span class="sr-only">Toggle navigation</span>
                                            <span class="icon-bar"></span>
                                            <span class="icon-bar"></span>
                                            <span class="icon-bar"></span>
                                        </button>
                                        <a id="nav-brand" class="navbar-brand " href="#">Project name <span
                                                class="fa fa-angle-right"></span></a>
                                    </div>
                                    <div class="navbar-collapse collapse horizon-nav">
                                        <ul id="home-page" class="nav navbar-nav ">
                                            <li id="activ"><a href="#">Activity</a></li>
                                        </ul>
                                        <ul id="main-menu" class="nav navbar-nav navbar-right">
                                            <li id="profile"><a id="account" href="#" class="dropdown-toggle ">
                                                <img class="img-circle" src="../static/images/1.jpg"
                                                     style="margin-right:5%;"/>Mohamed</a>
                                            </li>
                                            <li id="logout"><a href="#">logout</a>
                                            </li>
                                        </ul>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!--==========End Navbar=========-->
        <!--==========Start Divs=========-->
        <!-- this is main Div that contain navbar divs  -->

        <div  id="content" class="yellow col-xs-12">

            <!-- add task here !! -->
            <div ng-controller="taskManagerController" >
                <div id="task-panel" class="fadein fadeout showpanel panel" ng-show="toggle">
                    <div class="panel-heading ">
                        <!--<i class="panel-title-icon fa fa-tasks"></i>-->
                        <div class="panel-heading-controls">
                            <span class="panel-title">Recent Tasks</span>
                            <button ng-click="toggle = !toggle" class="btn-panel">Add New Task</button>
                            <button class="btn-panel " confirmed-click="archiveTasks()"
                                    ng-confirm-click="Would you like to archive completed tasks?">Clear completed tasks
                            </button>
                        </div>
                    </div>
                    <div class="panel-body">
                        <div class="task" ng-repeat="task in tasks">
                <span ng-if="task.taskPriority=='HIGH'" class="priority priority-red">
                    {{task.taskPriority}}
                </span>
                <span ng-if="task.taskPriority=='MEDIUM'" class="priority priority-yellow">
                    {{task.taskPriority}}
                </span>
                <span ng-if="task.taskPriority=='LOW'" class="priority priority-green">
                    {{task.taskPriority}}
                </span>
                            <div class="action-checkbox">
                                <input id="{{task._links.self.href}}" type="checkbox" value="{{task._links.self.href}}"
                                       ng-checked="selection.indexOf(task._links.self.href) > -1"
                                       ng-click="toggleSelection(task._links.self.href)"/>
                                <label for="{{task._links.self.href}}"></label>
                            </div>
                            <div ng-if="task.taskStatus=='COMPLETED'">
                                <a href="#" class="checkedClass">
                                    {{task.taskName}}
                                    <span class="action-status">{{task.taskStatus}}</span>
                                </a>
                            </div>
                            <div ng-if="task.taskStatus=='ACTIVE'">
                                <a href="#" class="uncheckedClass">
                                    {{task.taskName}}
                                    <span class="action-status">{{task.taskStatus}}</span>
                                </a>
                            </div>
                        </div>
                    </div>
                </div>
                <div id="add-task-panel" class="fadein fadeout addpanel panel" ng-hide="toggle">
                    <div class="panel-heading">
                        <div class="panel-heading-controls">
                            <i class="panel-title-icon fa fa-plus"></i>
                            <span class="panel-title panel-title2">Add Task</span>
                            <button ng-click="toggle = !toggle" class="btn-panel">Show All Tasks</button>
                        </div>
                    </div>
                    <div class="panel-body">
                        <div class="task">
                            <table class="add-task">
                                <tr>
                                    <td>Task Name:</td>
                                    <td><input type="text" ng-model="taskName"/></td>
                                </tr>
                                <tr>
                                    <td>Task Description:</td>
                                    <td><input type="text" ng-model="taskDesc"/></td>
                                </tr>
                                <tr>
                                    <td>Task Status:</td>
                                    <td>
                                        <select ng-model="taskStatus"
                                                ng-options="status as status for status in statuses">
                                            <option value="">-- Select --</option>
                                        </select>
                                    </td>
                                </tr>
                                <tr>
                                    <td>Task Priority:</td>
                                    <td>
                                        <select ng-model="taskPriority"
                                                ng-options="priority as priority for priority in priorities">
                                            <option value="">-- Select --</option>
                                        </select>
                                    </td>
                                </tr>
                                <tr>
                                    <td><br/>
                                        <button ng-click="addTask()" class="btn-panel-big">Add New Task</button>
                                    </td>
                                </tr>
                            </table>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!--==========End Divs=========-->
    </div>

    <!--==========End Section Project=========-->


</div>





</body>
</html>

App.JS

var taskManagerModule = angular.module('taskManagerApp', ['ngAnimate']);

taskManagerModule.controller('taskManagerController', function ($scope,$http) {

    var urlBase="";
    $scope.toggle=true;
    $scope.selection = [];
    $scope.statuses=['ACTIVE','COMPLETED'];
    $scope.priorities=['HIGH','LOW','MEDIUM'];
    $http.defaults.headers.post["Content-Type"] = "application/json";

    function findAllTasks() {
        //get all tasks and display initially
        $http.get(urlBase + '/tasks/search/findByTaskArchived?archivedfalse=0').
            success(function (data) {
                if (data._embedded != undefined) {
                    $scope.tasks = data._embedded.tasks;
                } else {
                    $scope.tasks = [];
                }
                for (var i = 0; i < $scope.tasks.length; i++) {
                    if ($scope.tasks[i].taskStatus == 'COMPLETED') {
                        $scope.selection.push($scope.tasks[i].taskId);
                    }
                }
                $scope.taskName="";
                $scope.taskDesc="";
                $scope.taskPriority="";
                $scope.taskStatus="";
                $scope.toggle='!toggle';
            });
    }

    findAllTasks();

    //add a new task
    $scope.addTask = function addTask() {
        if($scope.taskName=="" || $scope.taskDesc=="" || $scope.taskPriority == "" || $scope.taskStatus == ""){
            alert("Insufficient Data! Please provide values for task name, description, priortiy and status");
        }
        else{
         $http.post(urlBase + '/tasks', {
             taskName: $scope.taskName,
             taskDescription: $scope.taskDesc,
             taskPriority: $scope.taskPriority,
             taskStatus: $scope.taskStatus
         }).
          success(function(data, status, headers) {
             alert("Task added");
             var newTaskUri = headers()["location"];
             console.log("Might be good to GET " + newTaskUri + " and append the task.");
             // Refetching EVERYTHING every time can get expensive over time
             // Better solution would be to $http.get(headers()["location"]) and add it to the list
             findAllTasks();
            });
        }
    };

    // toggle selection for a given task by task id
      $scope.toggleSelection = function toggleSelection(taskUri) {
        var idx = $scope.selection.indexOf(taskUri);

        // is currently selected
        // HTTP PATCH to ACTIVE state
        if (idx > -1) {
          $http.patch(taskUri, { taskStatus: 'ACTIVE' }).
          success(function(data) {
              alert("Task unmarked");
              findAllTasks();
            });
          $scope.selection.splice(idx, 1);
        }

        // is newly selected
        // HTTP PATCH to COMPLETED state
        else {
          $http.patch(taskUri, { taskStatus: 'COMPLETED' }).
          success(function(data) {
              alert("Task marked completed");
              findAllTasks();
            });
          $scope.selection.push(taskUri);
        }
      };


    // Archive Completed Tasks
      $scope.archiveTasks = function archiveTasks() {
          $scope.selection.forEach(function(taskUri) {
              if (taskUri != undefined) {
                  $http.patch(taskUri, { taskArchived: 1});
              }
          });
          alert("Successfully Archived");
          console.log("It's risky to run this without confirming all the patches are done. when.js is great for that");
          findAllTasks();
      };

});

//Angularjs Directive for confirm dialog box
taskManagerModule.directive('ngConfirmClick', [
    function(){
         return {
             link: function (scope, element, attr) {
                 var msg = attr.ngConfirmClick || "Are you sure?";
                 var clickAction = attr.confirmedClick;
                 element.bind('click',function (event) {
                     if ( window.confirm(msg) ) {
                         scope.$eval(clickAction);
                     }
                 });
             }
         };
 }]);

Spring security config :

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService userDS;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/register","/").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .usernameParameter("email")
                .passwordParameter("password")
                .defaultSuccessUrl("/dashboard")
                .permitAll()
                .and()
                .logout().logoutSuccessUrl("/login?logout")
                .permitAll();
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDS).passwordEncoder(passwordEncoder());
    }

    @Override
    protected UserDetailsService userDetailsService() {
        return userDS;
    }
}

Upvotes: 0

Views: 166

Answers (2)

Tarang Bhalodia
Tarang Bhalodia

Reputation: 1195

Check the console of your browser, I guess there will be an error of 'No access Control Allow Origin' present. So you need to implement a "CORS Filter" in your application, spring security does not allow request from different origins, so manually need to allow them. You will get many resources on how to implement CORS in your application.

I followed example given in url below:

http://websystique.com/springmvc/spring-mvc-4-angularjs-example/

thanks

Upvotes: 0

Ibrahim Mohamed
Ibrahim Mohamed

Reputation: 75

i solved the problem adding http.csrf().disable(); to spring security config

Upvotes: 2

Related Questions