繁体   English   中英

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

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

我有一个在前端具有Angular组件且在后端具有Java的应用程序。 我正在使用基于令牌的身份验证来提供安全性。 但是我遇到一个问题,当我发出POST请求时,会得到403-Forbidden状态代码。 所有的GET请求都可以正常工作。 我在Java方面检查了所有实现,看起来还不错。 我从StackOverFlow.com和其他论坛中签出了其他解决方案,他们建议禁用CSRF。 即使我实现了,我仍然得到403。有人对此有任何想法吗? 在此先感谢,这是我的代码。

这是我的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>

如您所见,我已在代码的第8行中禁用了CSRF。 这是我剩下的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"/>

在我的Angular方面,我这样调用资源:

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

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)更新安全性配置类以包括上述过滤器,如下所示

  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)现在,在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() {

来源: 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