AngularJS + Spring Security - Как установить токен CSRF в запросе POST?

0

В моей службе angularJS authService я отправляю запрос POST с учетными данными и именем пользователя в конечную точку сервера в отдельном домене. У меня есть CORSFilter, который в порядке, поскольку я могу успешно отправлять POST-данные, когда я отключу CSRF-защиту в классе SecurityConfiguration.

Что я делаю не так? Как отправить токен CSRF с моим POST-запросом?

authService.login (учетные данные)

response.login = function (credentials) {
      return $http({
        method: "POST",
        dataType: "json",
        url: baseUrl + "/authenticate",
        withCredentials: true,
        data: { username: credentials.username },
        headers: {
          'Authorization' : "Basic " + btoa(credentials.username + ":" + credentials.password),
          'Content-Type': 'application/json'
        }
      });
    };

CsrfHeaderFilter

public class CsrfHeaderFilter extends 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);
    }
}

SecurityConfiguration.java

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .httpBasic()
                .and()
                .authorizeRequests()
                .antMatchers("/**")
                .permitAll().anyRequest().authenticated()
                .and().csrf()
                .csrfTokenRepository(csrfTokenRepository())
                .and()
                .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class);
//                .addFilterAfter(new CsrfHeaderFilter(), SessionManagementFilter.class);
    }

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

    @Override
    protected UserDetailsService userDetailsService() {
        return customUserDetailsService;
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

}

UserController

    @RequestMapping(method = RequestMethod.POST, value = "/authenticate")
    @PreAuthorize("hasRole('ROLE_USER')")
    public @ResponseBody User login(@RequestParam String username) {

        User user = repo.getUserWithUsername(username);

        if (user == null) throw new NotFoundException();
        return user;
    }
Теги:
csrf
spring
csrf-protection

1 ответ

0

Попробуйте это, если у вас есть какая-то форма. Spring автоматически генерирует скрытый ввод с токеном CSRF, который вы можете использовать:

function getCsrfHeader() {
var csrfToken = $("input[name='_csrf']").val();

var headers = {}; 
headers["X-CSRF-TOKEN"] = csrfToken;
headers["_csrf"] = csrfToken;
return headers;
};


function postSomethingToServer() {
var headers = getCsrfHeader();

var req = {
    method: 'POST',
    url: URL,
    headers: headers,
    data: SOME_DATA
};

$http(req)
.success(function() { ... })
.error(function() { ... });
}
  • 0
    Что такое $$ j ("input [name = '_ csrf']"). Val (); ??

Ещё вопросы

Сообщество Overcoder
Наверх
Меню