web-dev-qa-db-ja.com

カスタムAngularJSログインページを使用したSpring Boot and Security

Spring SecurityのカスタムAngularJSログインページを実装していますが、認証に問題があります。

このチュートリアル/例に従って、その 例はローカルで正常に動作します

しかし、これを自分で実装しようとすると、認証が失敗します。私の間違いがどこにあるのかわかりません。

A POSTは資格情報を使用して/ loginに行われ、curlは例と同じです)、GETへのリダイレクトで302 Foundを受け取ります/ login /、404 Not Foundを返します。

POST to/loginを実行しようとすると、Springはデバッグログを生成しません。そのため、302にどのようにサービスを提供しているかわかりません。

私のコードは here で見つかります:

注目すべき変更(そしておそらく私の問題の原因):

  • ファイル構造の変更

  • 厳密にAngular(jQueryなし)を使用)-POSTリクエストを作成するために必要な別の関数になります

  • Wro4jの代わりにbowerを使用する

  • 角度コードのスタイル設定/スコープ

関連するSpring Securityの質問の多くは、POSTリクエストの形式が正しくないことを示唆していますが、私の例は(chrome = dev console)カスタム承認プロバイダの実装を提案する人もいますが、この例では必要ありません。私のものと例の違いは何なのかと困惑しています。StackExchangeを手伝ってください。あなたは私の唯一の希望です。

開発ツール: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;
        }
    }

}
28
Andrew

AuthenticationSuccessHandlerを追加して、リクエストをリダイレクトするデフォルトのSpring成功ハンドラをオーバーライドしてみてください。

private AuthenticationSuccessHandler successHandler() {
    return new AuthenticationSuccessHandler() {
      @Override
      public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        httpServletResponse.getWriter().append("OK");
        httpServletResponse.setStatus(200);
      }
    };
  }

構成に認証成功ハンドラを追加します

http.
                formLogin().successHandler(successHandler())
            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);
0
johnmin
  1. より多くのSpringロギングを有効にします。application.propertiesを作成して、以下を配置します。

_logging.level.ROOT=DEBUG_認証プロセスの詳細と実際のエラーが表示されます。

  1. CSRF保護が有効になっています。

    and().csrf(). csrfTokenRepository(csrfTokenRepository()). and(). addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);

    cSRFトークンはurlパラメータの代わりにcookieから抽出されます:

    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の値もリクエストで提供されることを確認する必要があります。

0
Alex Chernyshev