使用spring security csrf token

时间:2016-05-31 16:27:40

标签: java angularjs spring spring-security csrf

我目前在Apache HTTP Server上有一个单独的AngularJS,在Tomcat 8上有一个Spring启动后端。后端充当Rest API。我想保护我的应用程序。我有很多建议使用提供spring安全性的csrf令牌并使用angualrjs消耗它。但我真的不知道如何使用Angular JS通过表单验证用户并获取安全资源以在UI中呈现。

这是我的主要应用程序类:`

package org.test;
    import java.io.IOException;
    import java.security.Principal;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;

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 javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
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.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.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;

@SpringBootApplication
@RestController
public class TaliopjarApplication {

    @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(TaliopjarApplication.class, args);
    }

    @Configuration
    @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
    protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
        @Autowired
        public void globalConfig(AuthenticationManagerBuilder auth,DataSource dataSource) throws Exception{
            /*auth.inMemoryAuthentication().withUser("admin").password("123").roles("0");
            auth.inMemoryAuthentication().withUser("talent1").password("123").roles("1");*/

            auth.jdbcAuthentication()
                .dataSource(dataSource)
                .usersByUsernameQuery("select str_login as principal, str_password as credentials, true from t_user where str_login = ?")
                .authoritiesByUsernameQuery("select str_login as principal, ln_type as role from t_user where str_login = ?")
                .rolePrefix("ROLE_");

        }
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.httpBasic().and().authorizeRequests()
                    .antMatchers("/index.html", "/home.html", "/login.html", "/",
                            "/data/**","/myApp.js","/assets/**","/skilltalent").permitAll().anyRequest()
                    .authenticated()
                    .and().formLogin().loginPage("/login")
                    .permitAll().defaultSuccessUrl("/index.html")
                    .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;
        }
    }

}

这是我的角色应用

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

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

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

})
.controller('navigation',

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

        var self = this;

        self.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
            }).then(function(response) {
                if (response.data.name) {
                    $rootScope.authenticated = true;
                } else {
                    $rootScope.authenticated = false;
                }
                callback && callback($rootScope.authenticated);
            }, function() {
                $rootScope.authenticated = false;
                callback && callback(false);
            });

        }

        authenticate();

        self.credentials = {};
        self.login = function() {
            alert("llllll");
            authenticate(self.credentials, function(authenticated) {
                if (authenticated) {
                    console.log("Login succeeded")
                    $location.path("/");
                    self.error = false;
                    $rootScope.authenticated = true;
                } else {
                    console.log("Login failed")
                    $location.path("/login");
                    self.error = true;
                    $rootScope.authenticated = false;
                }
            })
        };

        self.logout = function() {
            $http.post('logout', {}).finally(function() {
                $rootScope.authenticated = false;
                $location.path("/");
            });
        }

    }).controller('home', function($http) {
var self = this;
$http.get('/resource/').then(function(response) {
    self.greeting = response.data;
})
});

当我只使用一台服务器(tomcat)时,一切正常,但我不知道如何使用前端的appache和后端的tomcat。

欢迎任何帮助,建议和经验。

0 个答案:

没有答案