不支持 Spring 安全 Angular Post

Posted

技术标签:

【中文标题】不支持 Spring 安全 Angular Post【英文标题】:Spring security Angular Post not supported 【发布时间】:2016-11-12 06:53:51 【问题描述】:

我正在处理待办事项列表,它工作正常,但是当我将 spring security 添加到项目并单击添加时,它给出了

2016-07-10 04:32:34.441 警告 6692 --- [nio-8080-exec-8] os.web.servlet.PageNotFound:请求方法'POST'不是 支持

这个问题的任何解决方案

SpringWebSecurityConfig:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    UserDetailsService userDS;

    @Override
    protected void configure(HttpSecurity http) throws Exception 

        http.csrf().disable();
        http
                .authorizeRequests()
                .antMatchers("/register", "/", "/home").permitAll()
                .antMatchers("/css/*").permitAll()
                .antMatchers("/images/*").anonymous()
                .antMatchers("/fonts/*").permitAll()
                .antMatchers("/js/**").permitAll()
                .antMatchers("/template/**").permitAll()
                .antMatchers("/favicon.ico").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;
    

控制器:

@Controller
public class TaskController 

    @RequestMapping("/task")
    public String task() 

        return "task";
    


task.html

<!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="#">Todx</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="/dashboard">&#35; Dashboard<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="/files">Files<span style="font-size:16px;"
                                                    class="pull-right hidden-xs showopacity fa fa-paperclip"></span></a>
                    </li>
                    <li><a href="/calendar">Calendar<span style="font-size:16px;"
                                                          class="pull-right hidden-xs showopacity fa fa-calculator"></span></a>
                    </li>
                    <li><a href="/addtocalendar">Add to calendar<span style="font-size:16px;"
                                                                      class="pull-right hidden-xs showopacity fa fa-calendar-o
"></span></a>
                    </li>
                    <li><a href="/hangout">Hangout<span style="font-size:16px;"
                                                        class="pull-right hidden-xs showopacity fa fa-video-camera

"></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="#"><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="#"></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 img-responsive"
                                                     src="/images/1.png"
                                                     style="margin-left:5; width: 50px;display: inline-flex "/></a>
                                            </li>
                                            <li id="logout"><a href="/logout">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">
                            <i class="panel-title-icon fa fa-tasks"></i>

                            <span class="panel-title">Recent Tasks</span>
                            <button ng-click="toggle = !toggle" class="btn-md btn-panel ">Add New Task</button>
                            <button class="btn-md btn-panel  " ng-click="archiveTasks()"> Clear completed
                                <!--ng-confirm-click="Would you like to archive completed tasks?">Clear completed tasks-->
                            </button>
                        </div>
                    </div>
                    <div class="panel-body">
                        <div style="text-align: left" 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 style="text-align: left" 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" class="form-group"/></td>
                                </tr>
                                <tr>
                                    <td>Task Description:</td>
                                    <td><input type="text" ng-model="taskDesc" class="form-group"/></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);
                     
                 );
             
         ;
 ]);

请注意,让它工作并检索所有任务,但帖子在网络开发人员 chrome 控制台中给出 405,我认为它在 spring security 中它之前在 spring security 上工作,但我不知道我做了什么,现在它不工作

【问题讨论】:

您发送 POST 的 URL 是什么?您可以发布处理该请求的控制器吗? 我将它以角度发布到 /tasks 您是否尝试设置接受标头?您的浏览器可能正在设置接受标头,而您的标头可能没有说它可以接受。 我听不懂 【参考方案1】:

默认情况下,假定所有对 URL 的传入请求都是 HTTP GET 类型。为了区分HTTP请求类型的映射,我们需要在@RequestMapping声明中明确指定HTTP请求方法

如果你尝试 POST 到这个 URL,Spring 会拒绝它。

尝试将注释更改为

@RequestMapping(value = "/task", method = RequestMethod.POST)
public String task() 

    return "task";

如果您已经有当前 GET 方法的外部引用,您仍然可以为 POST 方法创建附加定义,以便两者可以共存。您只需像这样为它们分配不同的 Java 方法名称

@RequestMapping(value = "/task", method = RequestMethod.GET)
public String task() 

    return "task";


@RequestMapping(value = "/task", method = RequestMethod.POST)
public String postTask() 

    return "task";

更新 1

如果你的控制器打算接收 Ajax 调用,你需要添加额外的注解(比如@ResponseBody)让 Spring MVC 知道这是一个支持 ajax 的控制器/方法

@ResponseBody
@RequestMapping(value = "/task", method = RequestMethod.POST)
public String task() 

    return "task";

更新 2

试试下面的。真的,我不知道 Spring Security 是否强制执行参数与方法签名,但可能是您的情况。

public String task(@RequestParam(value = "taskName") String taskName,
                   @RequestParam(value = "taskDescription") String  taskDescription,
                   @RequestParam(value = "taskPriority") String taskPriority, 
                   @RequestParam(value = "taskStatus") String taskStatus) 

    return "task";

【讨论】:

不,它不工作,加上它在添加弹簧安全之前工作 这不是 Spring 安全问题,因为它们返回 401 错误(禁止)。请看更新 它返回 405 错误:“方法不允许”异常:“org.springframework.web.HttpRequestMethodNotSupportedException”消息:“请求方法 'POST' 不支持”路径:“/tasks”状态:405时间戳:“2016-07-10T03:17:00.497+0000” 您是否将参数作为 JSON 发送到您的“/task”控制器? 我没有将它发送到 /task 控制器我使用 mongo data rest with angular 我在控制器中使用 /task 来检索页面【参考方案2】:

我发现我让另一个控制器访问 /files 的问题 与角度的post方法冲突

【讨论】:

以上是关于不支持 Spring 安全 Angular Post的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Rest 和 Spring 安全性通过 ldap 登录 Angular?

为 Angular 2 配置 Spring 安全性

发布请求不适用于 Spring 安全性和 Angular 5

带有 Spring 安全 webflux 的 Angular 6 被 CORS 阻止

java Spring和Angular的安全级别,使用JHipster

在 Jersey 和 Spring SAML 安全 SSO 验证之后路由到 Angular 组件