简体   繁体   English

Spring Security +基于Angular App REST令牌的身份验证= 403在POST上被禁止

[英]Spring Security + Angular App REST Token Based Authentication = 403 Forbidden on POST

I have an app which has Angular component on frontend and Java on backend. 我有一个在前端具有Angular组件且在后端具有Java的应用程序。 I am using Token based Authentication to provide security. 我正在使用基于令牌的身份验证来提供安全性。 But I am headed to an issue that when I make a POST request, I get 403-Forbidden status code. 但是我遇到一个问题,当我发出POST请求时,会得到403-Forbidden状态代码。 All the GET request works fine. 所有的GET请求都可以正常工作。 I checked all my implementation on the Java side and seems fine. 我在Java方面检查了所有实现,看起来还不错。 I checked out other solutions from StackOverFlow.com and other forums and they have advised to disabled the CSRF. 我从StackOverFlow.com和其他论坛中签出了其他解决方案,他们建议禁用CSRF。 Even though I implemented that, I am still getting 403. Has anyone have any idea about it? 即使我实现了,我仍然得到403。有人对此有任何想法吗? Thanks in advance and here is my code. 在此先感谢,这是我的代码。

This is my security.xml 这是我的security.xml

<security:http 
        realm="Portected API" 
        use-expressions="true" 
        auto-config="false" 
        create-session="stateless"
        entry-point-ref="unauthorzedEntiryPoint"
        authentication-manager-ref="authenticationManager">
        <security:csrf disabled="true"/>
        <security:custom-filter ref="authenticationTokenProcessingFilter" position="FORM_LOGIN_FILTER"/>
        <security:intercept-url pattern="/foo" method="POST" access="hasAnyRole('USER', 'ADMIN')"/>
        <security:intercept-url pattern="/bar" method="POST" access="hasAnyRole('USER', 'ADMIN')"/>
    </security:http>

As you can see, I have disabled the CSRF on line 8 in the code. 如您所见,我已在代码的第8行中禁用了CSRF。 And here is my other remaining parts of XML. 这是我剩下的XML的其他部分。

<security:global-method-security secured-annotations="enabled"/>

<security:authentication-manager id="authenticationManager">
    <security:authentication-provider user-service-ref="userDetailService">
            </security:authentication-provider>
</security:authentication-manager>


<beans:bean id="unauthorzedEntiryPoint" class="org.sec.config.security.UnauthorizedEntryPoint"/>

<beans:bean id="authenticationTokenProcessingFilter" class="org.sec.config.security.AuthenticationTokenProcessingFilter">
    <constructor-arg ref="userDetailService"/>
</beans:bean>

<beans:bean id="userDetailService" class="org.sec.config.security.UserDetailService"/>

<beans:bean name="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

In my Angular side, I am calling the resource like this: 在我的Angular方面,我这样调用资源:

Restangular.all('bar').post(barModel, {}, {'Sec-Token': $localStorage.userToken})
      .then(function (response) {
        deferred.resolve(response);
        vm.currentBlog = response;
        //rest of the code.
}

1) Add a filter class as shown below 1)添加一个过滤器类,如下所示

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);
}
}

2) Update the security config class to include the above filter as shown below 2)更新安全性配置类以包括上述过滤器,如下所示

  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.annotation.Configuration;
  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.EnableWebSecurity;
  import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  import org.springframework.security.web.csrf.CsrfFilter;
  import org.springframework.security.web.csrf.CsrfTokenRepository;
  import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;

  @Configuration
  @EnableWebSecurity
  public class SecurityConfig extends WebSecurityConfigurerAdapter{



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

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

} }

3) Now there is no need to include any additional header on the Restangular post call, sample code is shown below. 3)现在,在Restangular帖子调用中无需包含任何其他标题,示例代码如下所示。

$Restangular.all('/addData').customPOST(
                     {amount:$scope.newExpense.amount, reason:$scope.newExpense.reason,dateStr:''+$scope.newExpense.date  },
                    '',
                    {},
                    {
                        'ContentType':'application/x-www-form-urlencoded'
                    }
                ).then(function() {

Source : https://spring.io/blog/2015/01/12/the-login-page-angular-js-and-spring-security-part-ii 来源: https : //spring.io/blog/2015/01/12/the-login-page-angular-js-and-spring-security-part-ii

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM