Spring Загрузка и безопасность с пользовательской страницей входа в систему AngularJS

Я реализую пользовательскую страницу регистрации AngularJS для Spring Security, и у меня возникают проблемы с аутентификацией.

Я следую этому руководству/примеру, и их пример отлично работает локально: https://github.com/dsyer/spring-security-angular/tree/master/single

Однако, когда я пытаюсь реализовать это самостоятельно, я не могу аутентифицироваться, и я не уверен, где моя ошибка.

POST делается для /login с учетными данными, (завиток идентичен примеру), и я получаю 302 Найдено с перенаправлением на GET/login/, который возвращает 404 Not Found.

Когда я пытаюсь выполнить POST для входа/входа, Spring не генерирует отладочные журналы, поэтому я не уверен, как он обслуживает 302.

Мой код можно найти здесь: https://github.com/AndrewBell/spring-angular-starter/tree/master

Заметные изменения (и, скорее всего, источник моих проблем):

  • Изменения структуры файла

  • Использование строго Angular (Нет jQuery) - что приводит к другой функции, необходимой для выполнения запроса POST

  • Использование беседки вместо wro4j

  • Angular стиль кода/область охвата

Многие связанные вопросы Spring Security указывают, что запрос POST отформатирован некорректно, но мой, по-видимому, такой же, как в примере (по крайней мере, когда я копирую в curl в консоли Chrome chrome). Другие предлагают внедрение специализированных поставщиков авторизации, но в этом примере это не нужно, поэтому я недоумеваю, какая разница между моим и примером. Помогите мне в Stack Exchange, вы - моя единственная надежда.

Инструменты Dev: imgurDOTcom/a/B2KmV

Соответствующий код:

login.js

'use strict';
angular
    .module('webApp')
    .controller('LoginCtrl', ['$root`enter code here`Scope', '$scope', '$http', '$location', '$route', function($rootScope, $scope, $http, $location, $route) {
        console.log("LoginCtrl created.");

        var vm = this;
        vm.credentials = {
            username: "",
            password: ""
        };
        //vm.login = login;

        $scope.tab = function(route) {
            return $route.current && route === $route.current.controller;
        };

        var authenticate = function(callback) {

            $http.get('user').success(function(data) {
                console.log("/user success: " + JSON.stringify(data));
                if (data.name) {
                    console.log("And Authenticated!");
                    $rootScope.authenticated = true;
                } else {
                    console.log("But received invalid data.");
                    $rootScope.authenticated = false;
                }
                callback && callback();
            }).error(function(response) {
                console.log("/user failure." + JSON.stringify(response));
                $rootScope.authenticated = false;
                callback && callback();
            });

        };

        authenticate();

        $scope.login = function() {

            var data2 = 'username=' + encodeURIComponent(vm.credentials.username) +
                '&password=' + encodeURIComponent(vm.credentials.password);

            $http.post('login', data2, {
                headers : {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            }).success(function() {
                authenticate(function() {
                    if ($rootScope.authenticated) {
                        console.log("Login succeeded");
                        $location.path("/");
                        $scope.error = false;
                        $rootScope.authenticated = true;
                    } else {
                        console.log("Login failed with redirect");
                        $location.path("/login");
                        $scope.error = true;
                        $rootScope.authenticated = false;
                    }
                });
            }).error(function() {
                console.log("Login failed");
                $location.path("/login");
                $scope.error = true;
                $rootScope.authenticated = false;
            })
        };

        $scope.logout = function() {
            $http.post('logout', {}).success(function() {
                $rootScope.authenticated = false;
                $location.path("/");
            }).error(function() {
                console.log("Logout failed");
                $rootScope.authenticated = false;
            });
        }

    }]);

Ответ 1

Попробуйте добавить WebSecuritConfigAdapter

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
            .authorizeRequests()
            .antMatchers("/**").permitAll()
            .anyRequest().authenticated();
    }
}

Ответ 2

Есть одна вещь, связанная с login.js, что он вызывает authenticate() который вызывает /user, и вы получаете перенаправление на GET/login/. Spring ищет login.jsp, которого там нет, и в итоге получается 404 Not Found.

Вы можете заставить его работать, выполнив следующие шаги:

1) Удалите вызов authenticate() из строки 38 в login.js

2) Добавить URL для обработки входа, например:

http.
     formLogin().
     loginProcessingUrl("/perform_login").
     and().
     logout()
 ....

3) Измените ваш логин URL на "execute_login", например:

$http.post('perform_login', data2, {
            headers : {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
        })....

и это работает, вы получаете пользователя.

Обратитесь к http://www.baeldung.com/spring-security-login для настройки безопасности Spring.

Ответ 3

Этот тип ошибки, скорее всего, является проблемой конфигурации Spring Security.

когда я читаю вашу весеннюю безопасность, комментируется 'loginPage'.
Также ваш:

antMatchers("/index.html", "/home/**", "/login/**", "/bower_components/**", "/", "/main.js", "/login/", "/navigation/**","/login","login/","/login.html")

Кажется странным для меня

antMatchers("/index.html", "/home**", "/login**", "/bower_components**", "/main.js", "/navigation**")

Все должно быть в порядке.

И я не очень люблю Angular, но ваш метод authenticate() вызывается (сразу после его определения), и он выполняет GET для "пользователя", которого нет в вашем сопоставителе "allowAll".

Так что подумайте о том, чтобы сделать это по-другому. Добавляете ли вы средство сопоставления, что не является хорошей практикой для предоставления свободного доступа к данным пользователя. Или получите информацию о пользователе после аутентификации.

ура

Ответ 4

Как рекомендует @hya, вам нужно добавить аннотацию @EnableWebSecurity над вашим классом SecurityConfiguration.

@Configuration
@EnableWebSecurity(debug=true) // this makes it easier to debug
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
   ...
}