使用自定义AngularJS登录页面的Spring Boot和Security [英] Spring Boot and Security with custom AngularJS Login page

查看:129
本文介绍了使用自定义AngularJS登录页面的Spring Boot和Security的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Spring Security实现一个自定义AngularJS登录页面,我遇到了身份验证问题。

I'm implementing a custom AngularJS login page for Spring Security, and I'm having issues authenticating.

我正在关注本教程/示例,他们正在示例在本地工作正常: https://github.com/dsyer/spring-security-angular/tree / master / single

I'm following this tutorial/example, and their example works fine locally: https://github.com/dsyer/spring-security-angular/tree/master/single

但是,当我尝试自己实现这个时,我无法进行身份验证,而且我不确定我的错误在哪里是。

However, when I try to implement this myself, I'm not able to authenticate, and I'm not sure where my mistake is.

使用凭据进行/登录POST(curl与示例相同),我收到302 Found,重定向到GET / login /,返回404 Not Found。

当我尝试POST到/ login时,Spring不生成任何调试日志,所以我'我不知道它是如何为302服务的。

When I try to POST to /login, the Spring does not generate any debug logs, so I'm not sure how it is serving the 302.

我的代码可以在这里找到: https://github.com/AndrewBell/spring-angular-starter/tree/master

My code can be found here: https://github.com/AndrewBell/spring-angular-starter/tree/master

值得注意的变化(和很可能是我的问题的来源):

Notable changes (And most likely the source of my issues):


  • 文件结构更改

  • File structure changes

严格使用Angular(无jQuery) - 导致发出POST请求所需的功能不同

Using strictly Angular (No jQuery) - Which results in a different function needed to make the POST request

使用bower而不是wro4j

Using bower instead of wro4j

角度代码样式/范围

许多相关Spring Security问题表明POST请求是表单错误地说,但是我看起来和示例相同(至少当我在chrome dev控制台中复制到curl时)。其他人建议实现自定义授权提供程序,但在示例中不需要它,因此我对我和示例之间的区别感到困惑。帮我Stack Exchange,你是我唯一的希望。

Many related Spring Security questions suggest the POST request is formatted incorrectly, but mine appears to be the same as the example (at least when I copy to curl in chrome dev console). Others suggest implementing custom authorization providers, but it is not needed in the example, so I'm perplexed to what the difference is between mine and the example. Help me Stack Exchange, you're my only hope.

开发工具:imgurDOTcom / a / B2KmV

Dev Tools: 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;
            });
        }

    }]);

application.java

package com.recursivechaos.springangularstarter;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.WebUtils;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@SpringBootApplication
@RestController
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @RequestMapping("/user")
    public Principal user(Principal user) {
        return user;
    }

    @RequestMapping("/resource")
    public Map<String, Object> home() {
        Map<String, Object> model = new HashMap<>();
        model.put("id", UUID.randomUUID().toString());
        model.put("content", "Hello World");
        return model;
    }

    @Configuration
    @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
    protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.
                formLogin().
                //loginPage("/#/login").
            and().
                logout().
            and().
                authorizeRequests().
                antMatchers("/index.html", "/home/**", "/login/**", "/bower_components/**", "/", "/main.js", "/login/", "/navigation/**","/login","login/","/login.html").
                permitAll().
                anyRequest().
                authenticated().
            and().
                csrf().
                csrfTokenRepository(csrfTokenRepository()).
            and().
                addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
        }

        private Filter csrfHeaderFilter() {
            return new OncePerRequestFilter() {
                @Override
                protected void doFilterInternal(HttpServletRequest request,
                                                HttpServletResponse response, FilterChain filterChain)
                    throws ServletException, IOException {
                    CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
                        .getName());
                    if (csrf != null) {
                        Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
                        String token = csrf.getToken();
                        if (cookie == null || token != null
                            && !token.equals(cookie.getValue())) {
                            cookie = new Cookie("XSRF-TOKEN", token);
                            cookie.setPath("/");
                            response.addCookie(cookie);
                        }
                    }
                    filterChain.doFilter(request, response);
                }
            };
        }

        private CsrfTokenRepository csrfTokenRepository() {
            HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
            repository.setHeaderName("X-XSRF-TOKEN");
            return repository;
        }
    }

}


推荐答案

login.js 有一件事就是调用 authenticate()调用/用户,你得到重定向到GET / login /。 Spring会查找不存在的 login.jsp ,最终会找到404 Not Found。

There is one thing worng with login.js that it invokes authenticate() which calls /user and you get a redirect to GET /login/. Spring looks for login.jsp which is not there and end up with 404 Not Found.

您可以通过以下步骤使其工作:

You can make it work by taking following steps:

1)从login.js第38行删除 authenticate()的调用

1) Remove invocation of authenticate() from line 38 in login.js

2)添加登录处理URL,如:

2) Add login processing URL like:

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

3)更改您的登录URL像'perform_login'一样:

3) Change your login URL to 'perform_login' like:

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

它有效,你得到了用户。

and it works, you get the user.

参考 http://www.baeldung.com/spring-security-login

这篇关于使用自定义AngularJS登录页面的Spring Boot和Security的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆