簡體   English   中英

405 方法不允許,spring 啟動,但我使用 csrf 令牌 header

[英]405 Method Not Allowed, spring boot, but i used csrf token header

我正在使用 Spring 啟動 Web 應用服務器。 在開發的早期,我使用設置http.csrf().disable()和 web 頁面運行良好。 但是自從禁用設置被擦除后,錯誤只發生在主機地址頁面 當我請求 GET 時,它工作得很好,但是,它不適用於 POST、PUT、DELETE ......當我在我的本地主機上測試時,所有請求都工作,包括這些方法。

Already, I used csrf token header, hidden csrf inputs of forms, and beforeSend that set csrf header in ajax. 我什至更改了 nginx 設置( error_page 405 =200 $uri; ),但它保持不變。 這是我的環境。

JDK 11
spring 2.3.5
AWS EC2 - 亞馬遜 Linux 2 AMI
AWS RDS-PostgreSQL 13
AWS S3 Nginx 1.18.0
gradle 5.6.4
thymeleaf

請問有誰可以幫助我嗎?

我的 Github 存儲庫鏈接

# aws server- nohup.out
[ec2-user@teamcoder-webservice ~]$ vim ~/app/step3/nohup.out
2020-12-01 23:24:18.953  INFO 3697 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@3ad85136, org.springframework.security.web.context.SecurityContextPersistenceFilter@2bc426f0, org.springframework.security.web.header.HeaderWriterFilter@176f7f3b, org.springframework.security.web.csrf.CsrfFilter@7d3c09ec, org.springframework.security.web.authentication.logout.LogoutFilter@1f53481b, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@7f93dd4e, org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter@5ad5be4a, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@33425811, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@4cb2918c, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@737d100a, org.springframework.security.web.session.SessionManagementFilter@58740366, org.springframework.security.web.access.ExceptionTranslationFilter@4af45442, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@671c4166]
2020-12-01 23:24:20.068  INFO 3697 --- [           main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page template: index
2020-12-01 23:24:20.550  INFO 3697 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8081 (http) with context path ''
2020-12-01 23:24:20.552  INFO 3697 --- [           main] DeferredRepositoryInitializationListener : Triggering deferred initialization of Spring Data repositories…
2020-12-01 23:24:21.474  INFO 3697 --- [           main] DeferredRepositoryInitializationListener : Spring Data repositories initialized!
2020-12-01 23:24:21.499  INFO 3697 --- [           main] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
2020-12-01 23:24:21.527  INFO 3697 --- [           main] c.j.team.teamcoder.TeamCoderApplication  : Started TeamCoderApplication in 17.806 seconds (JVM running for 19.458)
2020-12-01 23:24:23.438  INFO 3697 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-12-01 23:24:23.443  INFO 3697 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-12-01 23:24:23.460  INFO 3697 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 17 ms
2020-12-02 03:05:22.223  WARN 3697 --- [nio-8081-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
# /etc/nginx/nginx.conf

http {
...
 server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
        include /etc/nginx/conf.d/service-url.inc;

        location / {
                limit_except GET POST PUT DELETE {
                        deny all;
                }
                proxy_pass $service_url;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
        }
        error_page 405  =200 $uri;

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}
#after change upper configuration

[ec2-user@teamcoder-webservice nginx]$ sudo /usr/sbin/nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

另外,下面的代碼是 java spring 引導代碼。

<!--ajax non-used request in "user_info.html"-->
<form th:action="@{'/api/v1/user/pic/' + ${user.id}}" method="post" enctype="multipart/form-data" name="pictureForm">
    <table>
        <tr><td><label th:for="picture">Profile Image</label></td>
            <td><input type="file" id="picture" name="picture" accept="image/png, image/jpeg" /></td></tr>
        <tr><td><img th:src="@{${user.picture}}" id="picture_img" alt="put your image"></td>
            <td><input type="button" name="Upload" value="Upload" onclick="submit_file_form(document.forms['pictureForm'].picture, 'pictureForm');" class="btn btn-info"/></td></tr>
    </table>
    <input type="hidden" name="pastPath" id="pastPath" th:value="${user.picture}"/>
    <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
</form>
//ajax used request in "user_info.html" -> "userInfo.js"

...

const csrfToken = $('#_csrf').attr('content');
const csrfHeader = $('#_csrf_header').attr('content');


var user_info = {

    init : function () {
        var _this = this;

        $('#btn-update').on('click', function () {
            _this.update();
        }); 

        $('#btn-delete').on('click', function () {
            _this.delete();
        });
    },
    update : function () {
        var data = {
            name: $('#name').val(),
            tags: commaToArray(convertTags($('#tags').val())),
            email: $('#email').val(),
            birth: $('#birth').val(),
            education: $('#education').val().toUpperCase(),
            location: $('#location').val()
        };

        var id = $('#id').val();

        $.ajax({
            type: 'PUT', 
            url: '/api/v1/user/'+id,
            dataType: 'json',
            contentType:'application/json; charset=utf-8',
            data: JSON.stringify(data),
            beforeSend: function (xhr){
                xhr.setRequestHeader(csrfHeader, csrfToken);
            }
        }).done(function() {
            alert('your information is modified');
            window.location.href = '/';
        }).fail(function (error) {
            alert(JSON.stringify(error));
        });
    },
...
<!-- in html header -->

<meta id="_csrf" th:name="${_csrf.parameterName}" th:content="${_csrf.token}"/>
<meta id="_csrf_header" name="_csrf_header" th:content="${_csrf.headerName}"/>
@RequiredArgsConstructor
@RestController
public class UserApiController {

    private  final UserService userService;
    private final RoleService roleService;

    @PutMapping("/api/v1/user/{id}")
    public Long update(@PathVariable String id,
                       @RequestBody UserUpdateRequestDto requestDto){

        roleService.reloadRolesForAuthenticatedUser(Role.USER.getKey());
        return userService.update(Long.valueOf(id), requestDto);
    }
}

@RequiredArgsConstructor
@RestController
public class FileController {

    private final UserService userService;]
    private final S3Service s3Service;

    @PostMapping("/api/v1/user/pic/{id}")
    public String updateUserPic(@PathVariable String id,
                                @RequestParam("pastPath") String pastPath,
                            @RequestPart("picture") MultipartFile multipartFile) throws IOException {

        String uploadDir = s3Service.upload(pastPath, multipartFile,"users/");
        userService.updatePic(Long.valueOf(id), uploadDir);

        return "You successfully uploaded " + uploadDir + "!";
    }
}
//SecurityConfig.java

@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final CustomOAuth2UserService customOAuth2UserService;

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/css/**", "/js/**", "/assets/img/**", "/lib/**", "/user-photos/**", "/group-files/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .and()
                .authorizeRequests()  
                .antMatchers("/", "/logoption","/user/denied", "/search/**", "/privacy/rule","/profile").permitAll()  
                .antMatchers("/api/v1/user/**", "/api/v1/**").hasRole("GUEST")
                .antMatchers("/api/v1/group/**", "/group/**", "/api/v1/participate/**").hasRole("USER") 
                .anyRequest().authenticated()   
            .and()
                .logout().logoutSuccessUrl("/")
                .deleteCookies("JSESSIONID")
                .invalidateHttpSession(true)
            .and()
                .exceptionHandling()
                .accessDeniedPage("/user/denied")
            .and()
                .oauth2Login()
                    .loginPage("/logoption")
                    .defaultSuccessUrl("/")
                    .userInfoEndpoint()// after oauth2 login
                        .userService(customOAuth2UserService); 

    }
    
    //for Spring Security
    @Bean
    public ServletListenerRegistrationBean<HttpSessionEventPublisher> httpSessionEventPublisher() {
        return new ServletListenerRegistrationBean<>(new HttpSessionEventPublisher());
    }
}

嘗試將這些添加到您的 SecurityConfig:

http.cors().and()....

和 CORS 配置:

@Bean
public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");  // TODO: lock down before deploying
    config.addAllowedHeader("*");
    config.addExposedHeader(HttpHeaders.AUTHORIZATION);
    config.addAllowedMethod("*");
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM