Spring CSRF + AngularJs

我已经尝试过许多关于该主题的方法,但没有人适合我。

我在Spring MVC 4.1.7,Spring Security 3.2.3和MySQL + Tomcat7上都有基本的CRUD。

问题是,当我尝试使用AngularJS发布表单时,我一直被错误403(访问被拒绝)阻止。

我发现我需要发送带有POST请求的CSRF_TOKEN,但是我不知道怎么办!

我尝试了许多不同的方法,但没有人起作用。

我的文件

Controller.js

$scope.novo = function novo() {

if($scope.id){

alert("Update - " + $scope.id);

}

else{

var Obj = {

descricao : 'Test',

saldo_inicial : 0.00,

saldo : 33.45,

aberto : false,

usuario_id : null,

ativo : true

};

$http.post(urlBase + 'caixas/adicionar', Obj).success(function(data) {

$scope.caixas = data;

}).error(function(data) {alert(data)});

}

};

Spring-security.xml

<beans:beans xmlns="http://www.springframework.org/schema/security"

xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/security

http://www.springframework.org/schema/security/spring-security.xsd">

<!-- enable use-expressions -->

<http auto-config="true" use-expressions="true">

<intercept-url pattern="/seguro**"

access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />

<intercept-url pattern="/seguro/financeiro**"

access="hasAnyRole('ROLE_FINANCEIRO','ROLE_ADMIN')" />

<!-- access denied page -->

<access-denied-handler error-page="/negado" />

<form-login login-page="/home/" default-target-url="/seguro/"

authentication-failure-url="/home?error" username-parameter="inputEmail"

password-parameter="inputPassword" />

<logout logout-success-url="/home?logout" />

<!-- enable csrf protection -->

<csrf />

</http>

<!-- Select users and user_roles from database -->

<authentication-manager>

<authentication-provider>

<password-encoder hash="md5" />

<jdbc-user-service data-source-ref="dataSource"

users-by-username-query="SELECT login, senha, ativo

FROM usuarios

WHERE login = ?"

authorities-by-username-query="SELECT u.login, r.role

FROM usuarios_roles r, usuarios u

WHERE u.id = r.usuario_id

AND u.login = ?" />

</authentication-provider>

</authentication-manager>

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<display-name>Barattie ~ Soluções Integradas</display-name>

<!-- The definition of the Root Spring Container shared by all Servlets

and Filters -->

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>

/WEB-INF/spring/spring-security.xml

/WEB-INF/spring/spring-database.xml

/WEB-INF/spring/spring-hibernate.xml

</param-value>

</context-param>

<context-param>

<param-name>com.sun.faces.writeStateAtFormEnd</param-name>

<param-value>false</param-value>

</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

<!-- Processes application requests -->

<servlet>

<servlet-name>appServlet</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<init-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>appServlet</servlet-name>

<url-pattern>/home</url-pattern>

<url-pattern>/</url-pattern>

</servlet-mapping>

<!-- Spring Security -->

<filter>

<filter-name>springSecurityFilterChain</filter-name>

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>

</filter>

<filter-mapping>

<filter-name>springSecurityFilterChain</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<error-page>

<exception-type>java.lang.Throwable</exception-type>

<location>/erro</location>

</error-page>

我试图在客户端xsrf上添加重命名,但我一直拒绝访问。

var app = angular.module('myApp', []).config(function($httpProvider) {

$httpProvider.defaults.xsrfCookieName = '_csrf';

$httpProvider.defaults.xsrfHeaderName = 'X-CSRF-Token';

});

我试图实现这样的过滤器。

package sys.barattie.util;

import java.io.IOException;

import javax.servlet.FilterChain;

import javax.servlet.ServletException;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.security.web.csrf.CsrfToken;

import org.springframework.web.filter.OncePerRequestFilter;

public class CsrfFilter 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 = new Cookie("XSRF-TOKEN", csrf.getToken());

cookie.setPath("/");

response.addCookie(cookie);

}

filterChain.doFilter(request, response);

}

}

并更改了我的弹簧安全性。

     <csrf token-repository-ref="csrfTokenRepository" />

<beans:bean id="csrfTokenRepository" class="org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository">

<beans:property name="headerName" value="X-XSRF-TOKEN" />

</beans:bean>

Web.xml

<filter>

<filter-name>csrfFilter</filter-name>

<filter-class>sys.barattie.util.CsrfFilter</filter-class>

</filter>

但这就像服务器未运行筛选器一样,我向其中添加了System.out.println,但在调试中看不到消息

回答:

我做了一些测试,最终得到了结果。

在我的登录控制器中,如果我的用户身份验证成功,我将使用AngularJS Token的名称创建一个令牌,如下所示。

CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());

if (csrf != null) {

Cookie cookie = new Cookie("XSRF-TOKEN", csrf.getToken());

cookie.setPath("/");

response.addCookie(cookie);

}

之后,我可以成功管理$ http.post。

我不知道这是否是最好的方法,但是对我有用吗?

感谢您的帮助@Joao Evangelista

以上是 Spring CSRF + AngularJs 的全部内容, 来源链接: utcz.com/qa/405010.html

回到顶部