春季安全403与禁用CSRF

发布于 2025-02-04 09:03:43 字数 3643 浏览 2 评论 0 原文

使用Spring Security,我研究了类似的问题,但他们说尝试禁用CORS& CSRF。

我在浏览器上使用它,因此我需要CSRF。但是,仅仅进行测试并不会改变结果。

在登录时,我将获得访问令牌和刷新令牌。

使用此令牌可为我提供403禁止响应代码。

的配置如下:

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

我认为可能与此过滤器有关

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

我 hits filterchain.dofilter(请求,响应)然后直接跳到异常捕获 objectmapper 行line

用户提交也是学生角色。

Using spring security, I've looked at similar questions but they say to try disable cors & csrf.

I am using it on the browser so I will need 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.

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

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

The user submitting is also of the Student role.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

落花随流水 2025-02-11 09:03:43

这线
userNamePasswordAuthenticationToken authtoken = new UserNamePasswordAuthenticationToken(电子邮件,null);

缺少当局:

usernamepasswordauthentication authtoken = new Usernamepasswordwordwordwordwordwordword authentication thord authentication thorgetication(电子邮件,null,null,oterities)

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

is missing authorities:

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

毁虫ゝ 2025-02-11 09:03:43

希望我的答案能有所帮助,
您可以将断点置于该行更改响应状态,然后检查它返回403的原因以及为什么它可以帮助您获得解决方案

  1. 在线路上丢下断点设置403状态,以查看从stackframes中发生的。

猜猜它可以返回403没有其他信息,但是必须将状态设置为响应,对吗?因此,将断点放在SetStatus方法中,我不知道它应该在tomcat lib,spring lib或servlet lib中定位。检查httpresponse,它们是多个实现,为那些setstatus/setCode方法设置了断点。 (接下来,您可以在httpresponsewrapper :: setstatus上accat acut ocation thit IT)

  1. 分析stackframes以查看那里发生了什么

请检查

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

  1. Drop a breakpoint on the line set the 403 status, to see how this happen from the stackframes.

Guess that it returns 403 without much other information, but it must need to set the status to the response, right? So drop a breakpoint to the setStatus method, I don't know where it should locate, in tomcat lib, spring lib, or servlet lib. Check the HttpResponse, they're several implementation, set the breakpoints for those setStatus/setCode methods. (Next you can see it acutally happens at HttpResponseWrapper::setStatus)

  1. Analyze the stackframes to see what's going on there

please check https://stackoverflow.com/a/73577697/4033979

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文