0

我正在学习 Spring-boot 和 Oauth2。我有几个问题。

我正在实施针对 CSRF 的保护

.csrf()
                .requireCsrfProtectionMatcher(new AndRequestMatcher(
                    new NegatedRequestMatcher(new AntPathRequestMatcher("/test", HttpMethod.OPTIONS.toString()))
                ));

这工作正常,但是当我尝试访问我的 API 上的另一个路径时,我收到了这条消息。

"error": "access_denied"
"error_description": "Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'."

我尝试在我的请求中使用 JSESSIONID 设置 cookie,但没有成功

Status
403 Prohibido Show explanation Loading time: 22
Request headers 
Accept: application/json
Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
Authorization: Bearer 4abe8cbc-a528-4d52-8e20-a0aa198056d2
Content-Type: application/json 
DNT: 1
Accept-Encoding: gzip, deflate
Accept-Language: es-ES,es;q=0.8,en;q=0.6,und;q=0.4
Cookie: JSESSIONID=3DB726CA18F6628719703891B7DCA0A2
Response headers 
Server: Apache-Coyote/1.1 
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0 
X-Frame-Options: DENY
Cache-Control: no-store 
Pragma: no-cache 
Content-Type: application/json;charset=UTF-8 
Transfer-Encoding: chunked 
Date: Tue, 05 Jan 2016 03:59:45 GMT

我也尝试在我的项目上设置我的 CSRF 过滤器,最糟糕的是,这并没有让我得到带有 JSESSIONID 的 Cookie。字面上什么都不做

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
CustomAuthenticationProvider customAuthenticationProvider;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(customAuthenticationProvider);
}

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.httpBasic().and().authorizeRequests()
            .antMatchers("/test").permitAll().anyRequest()
            .authenticated()
            .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;
}
}

知道我做错了什么吗?

编辑我找到了我认为的部分解决方案,但现在我有几个问题。

解决方案: 使我的 CrsfTokenRepository 成为@Bean

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

只为我做了一堂课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);
}

}

并将我的配置WebSecurityConfiguration移到我的Oauth2Configuration

@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

    @Autowired
    private CustomLogoutSuccessHandler customLogoutSuccessHandler;

    @Autowired
    private CsrfTokenRepository csrfTokenRepository;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources
                .resourceId(RESOURCE_ID);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                // Logout
                .logout()
                .logoutUrl("/oauth/logout")
                .logoutSuccessHandler(customLogoutSuccessHandler)
                .and()
                //Session management
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                //URI's to verify
                .authorizeRequests()
                .antMatchers("/test").hasRole("ADMIN")
                .antMatchers("/users").authenticated()
                .antMatchers("/**").authenticated()
                .antMatchers("/productos").hasAnyRole("ADMIN, VENDEDOR")
                .and()
                .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
                .csrf()
                .csrfTokenRepository(csrfTokenRepository);
    }
}

我的问题是:

  • 这个解决方案好吗?是个好习惯吗?
  • JSESSIONID 和 XSRF-Token 不需要附加在我的 angularjs 请求中吗?
4

0 回答 0