简体   繁体   English

Spring 安全 403 禁用 csrf

[英]Spring security 403 with disabled csrf

Using spring security, I've looked at similar questions but they say to try disable cors & csrf.使用 spring 安全性,我看过类似的问题,但他们说尝试禁用 cors 和 csrf。

I am using it on the browser so I will need csrf.我在浏览器上使用它,所以我需要csrf。 But just testing briefly doesn't change the outcome.但只是简单地测试并不会改变结果。

On login I get an access token and refresh token.登录时,我得到一个访问令牌和刷新令牌。

Using this token gives me a 403 forbidden response code.使用这个令牌会给我一个 403 禁止响应代码。

My configuration is the following:我的配置如下:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.authorizeRequests().antMatchers("/login").permitAll();
        http.authorizeRequests().antMatchers(GET, "/**").hasAnyAuthority("STUDENT");
        http.authorizeRequests().anyRequest().authenticated();
        http.addFilter(new CustomAuthenticationFilter(authenticationManagerBean()));
        http.addFilterBefore(new CustomAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);
    }

I think maybe its something to do with this filter but if I change forbidden.value to something else the result is still forbidden.value我认为这可能与此过滤器有关,但如果我将forbidden.value更改为其他内容,结果仍然是forbidden.value

public class CustomAuthorizationFilter extends OncePerRequestFilter { // INTERCEPTS EVERY REQUEST
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if(request.getServletPath().equals("/login")){ filterChain.doFilter(request,response); } // DO NOTHING IF LOGGING IN
        else{
            String authorizationHeader = request.getHeader(AUTHORIZATION);
            if(authorizationHeader != null && authorizationHeader.startsWith("Bearer ")){
                try {
                    String token = authorizationHeader.substring("Bearer ".length()); // TAKES TOKEN STRING AND REMOVES BEARER
                    // THIS NEEDS MAKING SECURE AND ENCRYPTED vvvvvvv
                    Algorithm algorithm = Algorithm.HMAC256("secret".getBytes()); // <<<<<<<<<<<<<<<<<<<<<<<
                    JWTVerifier verifier = JWT.require(algorithm).build(); // USING AUTH0
                    DecodedJWT decodedJWT = verifier.verify(token);
                    String email = decodedJWT.getSubject(); // GETS EMAIL
                    String[] roles = decodedJWT.getClaim("roles").asArray(String.class); // GETS ROLES
                    Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
                    stream(roles).forEach(role -> {  authorities.add(new SimpleGrantedAuthority(role)); }); // CONVERTS ALL USERS ROLE INTO AN AUTHORITY
                    UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(email, null); // PASSWORD IS NULL AT THIS POINT
                    SecurityContextHolder.getContext().setAuthentication(authToken); // INSERTS TOKEN INTO CONTEXT // THIS SHOWS AUTHENTICATED FALSE, DETIALS FALSE AND GRANTED AUTHORITIES EMPTY
                    filterChain.doFilter(request, response); // GETS TO THIS LINE HERE
                }
                catch (Exception e){
                    response.setHeader("error" , e.getMessage() );
                    response.setStatus(FORBIDDEN.value());
                    Map<String, String> error = new HashMap<>();
                    error.put("error_message", e.getMessage());
                    response.setContentType(APPLICATION_JSON_VALUE);

                    new ObjectMapper().writeValue(response.getOutputStream(), error); // THEN SKIPS RIGHT TO THIS LINE HERE EVEN IF BREAKPOINTING BEFORE
                }
            }
            else{ filterChain.doFilter(request, response); }
        }
    }
}

debugging shows it hits filterChain.doFilter(request, response) then jumps straight to the exception catch objectMapper line调试显示它命中filterChain.doFilter(request, response)然后直接跳转到异常 catch objectMapper

The user submitting is also of the Student role.提交的用户也是学生角色。

this line UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(email, null);这一行UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(email, null);

is missing authorities:缺少权威:

UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(email, null, authorities);

Hope that my answer can help, you can drop a breakpoint to the line change the response status, and then check who and why it returns 403, it can finally help you get the solution希望我的回答能帮到你,你可以在改变响应状态的行下下断点,然后查看返回403的人以及原因,最终可以帮你得到解决方案

  1. Drop a breakpoint on the line set the 403 status, to see how this happen from the stackframes.在设置 403 状态的行上放置一个断点,以从堆栈帧中查看这是如何发生的。

Guess that it returns 403 without much other information, but it must need to set the status to the response, right?猜猜它返回 403 没有太多其他信息,但它必须需要将状态设置为响应,对吧? So drop a breakpoint to the setStatus method, I don't know where it should locate, in tomcat lib, spring lib, or servlet lib.所以在 setStatus 方法中放一个断点,我不知道它应该在哪里,在 tomcat 库、spring 库或 servlet 库中。 Check the HttpResponse, they're several implementation, set the breakpoints for those setStatus/setCode methods.检查 HttpResponse,它们是几个实现,为那些 setStatus/setCode 方法设置断点。 (Next you can see it acutally happens at HttpResponseWrapper::setStatus) (接下来你可以看到它确实发生在 HttpResponseWrapper::setStatus)

  1. Analyze the stackframes to see what's going on there分析堆栈帧以查看发生了什么

please check https://stackoverflow.com/a/73577697/4033979请检查https://stackoverflow.com/a/73577697/4033979

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

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