2015-11-13 4 views
5

の404:https://spring.io/guides/tutorials/spring-security-and-angular-js/春のセキュリティ - 私は春ブーツ、春のセキュリティとAngularJSを使用した簡単な単一ページのアプリケーションを記述する方法について説明チュートリアルで働いてログアウト

私は現在ログインしているユーザーをログアウトすることはできません - ときI "/ログアウト" へのPOSTリクエストを実行し、私は "404が見つかりません" を取得 - Google Chromeのデバッガから画面:GETなぜ

enter image description here

を?私はPOSTを行った。なぜ "/ login?logout"ではなく、 "/ logout"ではなく?

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

春コード:

@SpringBootApplication 
@RestController 
public class UiApplication { 

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

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

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

    @Configuration 
    @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) 
    protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter { 
     @Override 
     protected void configure(HttpSecurity http) throws Exception { 
      http.httpBasic().and().authorizeRequests() 
        .antMatchers("/index.html", "/home.html", "/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; 
     } 
    } 

} 

全体AngularJSコード:

angular.module('hello', [ 'ngRoute' ]).config(function($routeProvider, $httpProvider) { 

    $routeProvider 
.when('/', {templateUrl : 'home.html', controller : 'home' }) 
.when('/login', { templateUrl : 'login.html', controller : 'navigation' }) 
.otherwise('/'); 

    $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 

}).controller('navigation', 

     function($rootScope, $scope, $http, $location, $route) { 

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

      var authenticate = function(credentials, callback) { 

       var headers = credentials ? { 
        authorization : "Basic " 
          + btoa(credentials.username + ":" 
            + credentials.password) 
       } : {}; 

       $http.get('user', { 
        headers : headers 
       }).success(function(data) { 
        if (data.name) { 
         $rootScope.authenticated = true; 
        } else { 
         $rootScope.authenticated = false; 
        } 
        callback && callback($rootScope.authenticated); 
       }).error(function() { 
        $rootScope.authenticated = false; 
        callback && callback(false); 
       }); 

      } 

      authenticate(); 
      $scope.credentials = {};    
      $scope.login = function() { 
       authenticate($scope.credentials, function(authenticated) { 
        if (authenticated) { 
         console.log("Login succeeded") 
         $location.path("/"); 
         $scope.error = false; 
         $rootScope.authenticated = true; 
        } else { 
         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(data) { 
        console.log("Logout failed") 
        $rootScope.authenticated = false; 
       });   
      } 

     }).controller('home', function($scope, $http) { 
      $http.get('/resource/').success(function(data) {   
       $scope.greeting = data; }) }); 

私は春に新たなんだ。ここのユーザーがクリックするボタンをログアウトするときに呼び出されるコードがあります。ここでは、チュートリアルから、全体のコードは - あまりにも動作しません。実際には

$scope.logout = function() { 
    $http.post('\logout') 
     .success(function() { 
      // on success logic 
     }) 
     .error(function (data) { 
      // on errorlogic 
     }); 
} 
+0

をあなたは私の答えを試してみたのですか? –

+1

あなたは何が起こったのか理解したい場合。実際には2つのログアウト要求があるため、POSTの代わりにGETを取得します。最初の1つは手動でPOSTを実行し、 "login?logout"リソースへのリダイレクトコードで応答を受信することです。次に、このリソースに対するGET要求が実行されます。 logoutSuccessHandlerを上書きすると、ログアウトリクエストからリダイレクトが除外されます(つまり、「ログアウト」リソースへのPOSTリクエストは1つだけになります)。 –

答えて

0

だからそれはこのようになります。この$http.post('\logout')

$http.post('logout', {})を変更しようログアウト成功ハンドラを追加するだけです。

@Component 
public class LogoutSuccess implements LogoutSuccessHandler { 

@Override 
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) 
     throws IOException, ServletException { 
    if (authentication != null && authentication.getDetails() != null) { 
     try { 
      httpServletRequest.getSession().invalidate(); 
      // you can add more codes here when the user successfully logs 
      // out, 
      // such as updating the database for last active. 
     } catch (Exception e) { 
      e.printStackTrace(); 
      e = null; 
     } 
    } 

    httpServletResponse.setStatus(HttpServletResponse.SC_OK); 

} 

} 

あなたのセキュリティに成功ハンドラを追加するだけです。春ブーツの新しいバージョンで設定

http.authorizeRequests().anyRequest().authenticated().and().logout().logoutSuccessHandler(logoutSuccess).deleteCookies("JSESSIONID").invalidateHttpSession(false).permitAll(); 
2

デフォルトごとにHTTP 200が返されますHttpStatusReturningLogoutSuccessHandlerというクラスがあります。そのJavadocは言う:

「これは 成功ログアウト時にリダイレクトが望まれていないREST型のシナリオで有用です」。

それが何か書く使用する:

 //... 
     .formLogin() 
     .and() 
     .logout().logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler()); 
+0

あなたは私の問題を解決しました、ありがとうございます。 –

関連する問題