Меню

Ошибка 403 spring security

I’m trying to secure my website using Spring Security following the guides on the web.

So on my server side I have the following classes.

My WebSecurityConfigurerAdapter:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements ApplicationContextAware {

    @Override
    protected void registerAuthentication(AuthenticationManagerBuilde rauthManagerBuilder) throws Exception {
        authManagerBuilder.inMemoryAuthentication().withUser("user").password("password").roles("ADMIN");
    }
}

My controller:

@Controller
//@RequestMapping("/course")
public class CourseController implements ApplicationContextAware {

    @RequestMapping(value="/course", method = RequestMethod.GET, produces="application/json")
    public @ResponseBody List<Course> get(  // The criterion used to find.
        @RequestParam(value = "what", required = true) String what,
        @RequestParam(value = "value", required = true) String value) {
        //.....
    }

    @RequestMapping(value = "/course", method = RequestMethod.POST, produces = "application/json")
    public List<Course> upload(@RequestBody Course[] cs) {
        
    }
}

What confused me very much is the server does not respond to the POST/DELETE method, while the GET method works fine. BTW, I’m using RestTemplate on the client side.

Exceptions are:

Exception in thread "main" org.springframework.web.client.HttpClientErrorException: 403 Forbidden
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
    at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:574)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:530)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:487)
    at org.springframework.web.client.RestTemplate.delete(RestTemplate.java:385)
    at hello.Application.createRestTemplate(Application.java:149)
    at hello.Application.main(Application.java:99)

I’ve searched the internet for days. Still don’t have a clue. Please help. Thanks so much

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.

Already on GitHub?
Sign in
to your account

Assignees

@jzheaux

Comments

@bleepbleepbleep

Summary

When I try to POST to a resource requiring authentication, I am redirected to a login page (as expected). Upon entering the username and password, I get a 403 access denied error. This works fine if I do a GET to the exact same resource. It’s only for a POST.

Actual Behavior

Receive 403 after successful authentication if authentication trigger is a POST to a protected resource.

Expected Behavior

Resource call should execute same as a GET.

Configuration

@OverRide
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(«//action/«).access(«isFullyAuthenticated()»)
.and().formLogin()
.and().csrf().disable();

Version

Tried 5.0.4 and 4.2.4

Sample

@jzheaux

@bleepbleepbleep, the behavior you specify is already supported:

@SpringBootApplication
public class DemoApplication {

	@Controller
	public static class ActionController {
		@GetMapping("/action")
		@ResponseBody
		String getOk() {
			return "<form action='/action' method='post'><button type='submit'>Go</button></form>";
		}

		@PostMapping("/action")
		@ResponseBody
		String postOk() {
			return "ok";
		}
	}

	@EnableWebSecurity
	public static class SecurityConfig extends WebSecurityConfigurerAdapter {
		@Override
		protected void configure(HttpSecurity http) throws Exception {
			http.authorizeRequests()
				.antMatchers("/action/**")
					.access("isFullyAuthenticated()")
					.and()
				.formLogin()
					.and()
				.csrf().disable();
		}

		@Bean
		@Override
		public UserDetailsService userDetailsService() {
			UserDetails user = User.withDefaultPasswordEncoder()
								.username("user")
								.password("password")
								.roles("USER")
								.build()

			return new InMemoryUserDetailsManager(user);
		}
	}

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}
}

In the above code, both GET /action and POST /action return a 200 OK once the user is authenticated.

Note the ant syntax for /action, which is where I think I could be misunderstanding your use case. Would you mind clarifying if you feel I’ve misunderstood? Otherwise, I’ll close this issue and recommend that you make a post to StackOverflow for further troubleshooting support.

@chandu-atina

@bleepbleepbleep From your statement GET works well and POST throws 403 error, I suspect that CSRF protect is enabled and the post request doesn’t include a valid csrf token.

But your sample code states that csrf is disabled, can you confirm the same from your application configuration to make sure that csrf is disabled?

@charlie39

this is something I am facing right now with spring security 5.1.5

@jzheaux

@charlie39 would you be able to provide a sample project that reproduces the issue you are experiencing?

@spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

@spring-projects-issues

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.

@solutionaddicts

Has anyone fixed this error?
I’m facing this issue when I trigger a POST request with couple of fields.
{
«timestamp»: «2020-02-06T19:58:23.636+0000»,
«status»: 403,
«error»: «Forbidden»,
«message»: «Access Denied»,
«path»: «/csor/security/greet»
}

I have CSRF disabled in security config as below:
@OverRide
public void configure(HttpSecurity http) throws Exception {
http
.headers().frameOptions().disable()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
// .antMatchers(«csor/security/authenticate/»).permitAll()
.antMatchers(«/v2/api-docs»,
«/swagger-resources/«,
«/swagger-ui.html»,
«/webjars/
«
).permitAll()
// .anyRequest().authenticated()
.and()
.csrf().disable();
//.and()
//.addFilter(new JwtAuthenticationFilter(authenticationManager()))
//.addFilter(new JwtAuthorizationFilter(authenticationManager()));
}

@VhiktorBrown

I’ve been experiencing this issue for the past 1 week now. I disabled csrf but I still get the same error. Any little help would be appreciated.

@danielptm

Im having the same issue.

@sarita-hirekhan

even i am facing this issue, how to resolve 403 error for POST api

java.lang.Object

org.springframework.security.web.authentication.Http403ForbiddenEntryPoint

All Implemented Interfaces:
AuthenticationEntryPoint

In the pre-authenticated authentication case (unlike CAS, for example) the user will
already have been identified through some external mechanism and a secure context
established by the time the security-enforcement filter is invoked.

Therefore this class isn’t actually responsible for the commencement of authentication,
as it is in the case of other providers. It will be called if the user is rejected by
the AbstractPreAuthenticatedProcessingFilter, resulting in a null authentication.

The commence method will always return an
HttpServletResponse.SC_FORBIDDEN (403 error).

Since:
2.0
See Also:
  • ExceptionTranslationFilter
  • Constructor Summary

    Constructors

  • Method Summary

    void

    commence(jakarta.servlet.http.HttpServletRequest request,
    jakarta.servlet.http.HttpServletResponse response,
    AuthenticationException arg2)

    Always returns a 403 error code to the client.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

  • Constructor Details

    • Http403ForbiddenEntryPoint

      public Http403ForbiddenEntryPoint()

  • Method Details

    • commence

      public void commence(jakarta.servlet.http.HttpServletRequest request,
      jakarta.servlet.http.HttpServletResponse response,
      AuthenticationException arg2)

      throws IOException

      Always returns a 403 error code to the client.

      Specified by:
      commence in interface AuthenticationEntryPoint
      Parameters:
      request — that resulted in an AuthenticationException
      response — so that the user agent can begin authentication
      arg2 — that caused the invocation
      Throws:
      IOException

In this article of spring security tutorial, we will see how to create a Spring Security custom 403 access denied page. we will take a look at the steps for spring security custom 403 page.

In Spring security, when an unauthorized user will try to access the secure/ protected page, spring security will throw an access denied exception. There is a default 403 access denied page available with spring security, or if we are using spring boot, it will show the infamous whitelabel error page. Spring security flexible architecture provides the option to customize the 403 access denied page.

1. Application Setup

Before we create spring security custom 403 access denied page, let’s look at our pom.xml file containing the required dependencies.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.3.1.RELEASE</version>
      <relativePath />
      <!-- lookup parent from repository -->
   </parent>
   <groupId>com.javadevjournal</groupId>
   <artifactId>spring-security-series</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>Spring Security Tutorial Series</name>
   <description>Series to explain the core Spring security concepts.</description>
   <properties>
      <java.version>1.8</java.version>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-security</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-thymeleaf</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-jpa</artifactId>
      </dependency>
      <dependency>
         <groupId>org.thymeleaf.extras</groupId>
         <artifactId>thymeleaf-extras-springsecurity5</artifactId>
         <version>3.0.4.RELEASE</version>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
         <exclusions>
            <exclusion>
               <groupId>org.junit.vintage</groupId>
               <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
         </exclusions>
      </dependency>
   </dependencies>
   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>
</project>

Our pom.xml file contains only required dependencies, and you may need more based on your use case. Also, if you are not using spring boot, the above file is not relevant to you but will give you the idea for the required dependencies.

2. Custom Access Denied Page

To replace the Spring Security custom access denied page, we need to create a custom HTML page for our application. I am using Thymeleaf to build the HTML page, but you can use any other templating engine of your choice. Here is our custom access denied page.

Below HTML is just a sample HTML. You may need different HTML for your production app.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <link href="https://fonts.googleapis.com/css?family=Raleway:500,800" rel="stylesheet" />
        <title>Access Denied</title>
    </head>
    <body>
        <use>
            <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve" class="whistle">
                <metadata></metadata>
                <g>
                    <g transform="translate(0.000000,511.000000) scale(0.100000,-0.100000)">
                        <path
                            d="M4295.8,3963.2c-113-57.4-122.5-107.2-116.8-622.3l5.7-461.4l63.2-55.5c72.8-65.1,178.1-74.7,250.8-24.9c86.2,61.3,97.6,128.3,97.6,584c0,474.8-11.5,526.5-124.5,580.1C4393.4,4001.5,4372.4,4001.5,4295.8,3963.2z"
                        />
                        <path
                            d="M3053.1,3134.2c-68.9-42.1-111-143.6-93.8-216.4c7.7-26.8,216.4-250.8,476.8-509.3c417.4-417.4,469.1-463.4,526.5-463.4c128.3,0,212.5,88.1,212.5,224c0,67-26.8,97.6-434.6,509.3c-241.2,241.2-459.5,449.9-488.2,465.3C3181.4,3180.1,3124,3178.2,3053.1,3134.2z"
                        />
                        <path
                            d="M2653,1529.7C1644,1445.4,765.1,850,345.8-32.7C62.4-628.2,22.2-1317.4,234.8-1960.8C451.1-2621.3,947-3186.2,1584.6-3500.2c1018.6-501.6,2228.7-296.8,3040.5,515.1c317.8,317.8,561,723.7,670.1,1120.1c101.5,369.5,158.9,455.7,360,553.3c114.9,57.4,170.4,65.1,1487.7,229.8c752.5,93.8,1392,181.9,1420.7,193.4C8628.7-857.9,9900,1250.1,9900,1328.6c0,84.3-67,172.3-147.4,195.3c-51.7,15.3-790.8,19.1-2558,15.3l-2487.2-5.7l-55.5-63.2l-55.5-61.3v-344.6V719.8h-411.7h-411.7v325.5c0,509.3,11.5,499.7-616.5,494C2921,1537.3,2695.1,1533.5,2653,1529.7z"
                        />
                    </g>
                </g>
            </svg>
        </use>
        <h1>403</h1>
        <h2>Not this time, access forbidden!</h2>
    </body>
</html>

3. Spring Security Configuration

We have the custom HTML in place. The next step is to configure the Spring Security custom 403 access denied page. To customize this page, Spring security provides the following options while configuring the HttpSecurity element.

  1. Configure access denied page using the accessDeniedPage().
  2. Use accessDeniedHandler() method.

The accessDeniedHandler() method provides more flexibility and control while customizing the access denied page in spring security, and we will use this option for this article.

3.1 Access Denied Handler

Spring security access denied handler provides us the flexibility and power to run the custom logic before redirecting user to the 403 page.To create a custom access denied handler with spring security, create a class by extending the <a aria-label="AccessDeniedHandler (opens in a new tab)" href="https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/access/AccessDeniedHandler.html" target="_blank" rel="noreferrer noopener" class="rank-math-link">AccessDeniedHandler</a> interface.

package com.javadevjournal.core.security.handlers;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.access.AccessDeniedHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CustomAccessDeniedHandler implements AccessDeniedHandler {

    private static final Logger LOG = LoggerFactory.getLogger(CustomAccessDeniedHandler.class);

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null) {

            LOG.info("User '" + authentication.getName() +
                "' attempted to access the URL: " +
                request.getRequestURI());
        }
        response.sendRedirect(request.getContextPath() + "/access-denied");
    }
}

The custom handler is only logging the information and redirecting user to the “access-denied” controller. If you look closely, at this point we have access to the request, response, exception and the authentication object. We can build any custom logic based on this information.

3.2. Access Denied Controller.

Next is to create a custom controller to handle the redirect and send use to the access denied page. This is a simple Spring MVC controller, but we have the flexibility to perform any additional logic before showing the page to the customer.

package com.javadevjournal.web.controller.error;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class AccessDeniedController {

    @GetMapping("/access-denied")
    public String getAccessDenied() {
        return "/error/accessDenied";
    }
}

3.3. Configuring the Custom Access Denied Handler.

We have created the following components for our custom access denied page:

  1. Custom HTML page.
  2. Custom access denied handler.
  3. Spring MVC controller.

The last part of the setup is to let Spring security know about our custom handler. It will do this as part of configuring spring security through the HttpSecurity component. Here is a simplified version of our Spring security configuration (You can check complete configuration on our GitHub Repository)

@EnableWebSecurity
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/login", "/register", "/home")
            .permitAll()
            .antMatchers("/account/**").hasAuthority("ADMIN")
            .and()
            .exceptionHandling().accessDeniedHandler(accessDeniedHandler())
            .and()
            ...
    }

    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        return new CustomAccessDeniedHandler();
    }
    
}

There are few important things in the above configuration.

  1. We are only allowing ADMIN authority to access the /account/**. This means any other user with different authority will get the 403 access denied exception.
  2. Since this is an exception handling, we are using the Spring security .excepTionHandling() method and telling that we like to handle the access denied use case by passing custom access denied handler to the accessDeniedHandler() method (.exceptionHandling().accessDeniedHandler(accessDeniedHandler()).
  3. Last part defines our custom handler as a spring managed bean.

4. Testing Application

Our setup is complete, let’s start our application and try to access the page. In the first screen shot (without custom access denied configuration), our application will show the default page.

Spring Security custom 403 access denied page

Once we active the configurations for spring security custom 403 access denied page. Let’s try to access the unauthorized section again by simply login to the system, this time, we will be greeted by our custom access denied page.

Spring Security custom 403 access denied page

Summary

In this article, we saw how to create a Spring Security custom 403 access denied page. We took a deep dive in to the different components to required to customize the access denied page for spring security application. As always, the source code for our Spring Security Course is available on the GitHub.

По умолчанию в Spring Security определенExceptionTranslationFilter, который обрабатывает исключения типаAuthenticationException иAccessDeniedException. Последнее осуществляется с помощью свойстваaccessDeniedHandler,, которое использует классAccessDeniedHandlerImpl.

Чтобы настроить это поведение для использования нашей собственной страницы, которую мы создали выше, нам нужно переопределить свойства классаExceptionTranslationFilter. Это можно сделать с помощью конфигурации Java или конфигурации XML.

3.1. Доступ запрещен к странице

Используя Java,we can customize the 403 error handling process by using the accessDeniedPage() or accessDeniedHandler() methods при настройке элементаHttpSecurity.

Давайте создадим конфигурацию аутентификации, которая ограничивает URL-адреса“/admin/** рольюADMIN и устанавливает страницу отказа в доступе на нашу пользовательскую страницуaccessDenied.jsp:

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
      // ...
      .and()
      .exceptionHandling().accessDeniedPage("/accessDenied.jsp");
}

Давайте посмотрим на эквивалентную конфигурацию XML для страницы с отказом в доступе:

3.2. Обработчик отказа в доступе

Использование обработчика отказа в доступе вместо страницы имеет то преимущество, что мы можем определить пользовательскую логику, которая будет выполняться перед перенаправлением на страницу 403. Для этогоwe need to create a class that implements the AccessDeniedHandler interface и отменяет методhandle().

Давайте создадим собственный классAccessDeniedHandler, который будет регистрировать предупреждающее сообщение для каждой попытки отказа в доступе с указанием пользователя, который сделал попытку, и защищенного URL, к которому он пытался получить доступ:

public class CustomAccessDeniedHandler implements AccessDeniedHandler {

    public static final Logger LOG
      = Logger.getLogger(CustomAccessDeniedHandler.class);

    @Override
    public void handle(
      HttpServletRequest request,
      HttpServletResponse response,
      AccessDeniedException exc) throws IOException, ServletException {

        Authentication auth
          = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null) {
            LOG.warn("User: " + auth.getName()
              + " attempted to access the protected URL: "
              + request.getRequestURI());
        }

        response.sendRedirect(request.getContextPath() + "/accessDenied");
    }
}

В конфигурации безопасностиwe’ll define the bean and set the custom AccessDeniedHandler:

@Bean
public AccessDeniedHandler accessDeniedHandler(){
    return new CustomAccessDeniedHandler();
}

//...
.exceptionHandling().accessDeniedHandler(accessDeniedHandler());

Если мы хотим настроить классCustomAccessDeniedHandler, определенный выше, с использованием XML, конфигурация будет выглядеть немного иначе:

When I was studying the spring-security framework recently, there was no problem with the login operation, but I was blocked by spring-security when I wanted to access a certain page resource, and I also reported an error of insufficient access with 403 permissions.

First let’s take a look at the error message:
The console prints this string of error messages:

org.springframework.security.access.AccessDeniedException: Access is denied
	at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84)
	at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:124)
	at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
	at java.base/java.lang.Thread.run(Thread.java:844)

After this problem occurs, after confirming that the code is correct, perform a debug test to see that the data has been transmitted. But found thisThe character is lowercaseWhile I amIn the spring-security.xml, the uppercase role information is configured.

  <security:http auto-config="true" use-expressions="false">
        <!-- Configure specific interception rules="Rules for request path" access="The person accessing the system must have the role of ROLE_USER" -->
        <security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/>

   </security:http>

Solution:
Use lowercase to uppercase by using toUpperCase() method

Summary: The reason for this error is simple. This is because the data I got in the database are all lowercase data.

Last Modified 2021.11.29

Add the following to redirect access denied user requests to the /WEB-INF/views/403.jsp page.

security.xml
<http>
  <access-denied-handler error-page="/403" />
  <intercept-url pattern="/users/bye_confirm" access="permitAll"/>
  <intercept-url pattern="/users/welcome" access="permitAll"/>
  <intercept-url pattern="/users/signUp" access="permitAll"/>
  <intercept-url pattern="/users/login" access="permitAll"/>
  <intercept-url pattern="/images/**" access="permitAll"/>
  <intercept-url pattern="/css/**" access="permitAll"/>
  <intercept-url pattern="/js/**" access="permitAll"/>
  <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
  <intercept-url pattern="/users/**" access="hasAnyRole('ROLE_ADMIN','ROLE_USER')"/>
  <intercept-url pattern="/bbs/**" access="hasAnyRole('ROLE_ADMIN','ROLE_USER')"/>
	
  <!-- omit -->
	  

You need to declare a handler for «/403» in the controller with the above configuration. Otherwise, you will get a 404 error.

Create a 403.jsp file and add the following method to your HomeController.

/403.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ page import="net.java_school.user.User" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>403</title>
<link rel="stylesheet" href="/css/screen.css" type="text/css" />
<script type="text/javascript" src="/js/jquery-3.2.1.min.js"></script>
</head>
<body>
<div id="wrap">

  <div id="header">
    <%@ include file="inc/header.jsp" %>
  </div>
    
  <div id="main-menu">
    <%@ include file="inc/main-menu.jsp" %>
  </div>
    
  <div id="container">
    <div id="content" style="min-height: 800px;">
      <div id="content-categories">Error</div>
      <h1>403</h1>
      Access is Denied.
    </div>
  </div>
    
  <div id="sidebar">
    <h1>Error</h1>
  </div>
    
  <div id="extra">
    <%@ include file="inc/extra.jsp" %>    
  </div>
    
  <div id="footer">
    <%@ include file="inc/footer.jsp" %>
  </div>
        
</div>

</body>
</html>
HomeController.java
@RequestMapping(value="/403", method={RequestMethod.GET,RequestMethod.POST})
public String error403() {
  return "403";
}

Exclude 403 error from error page configuration in web.xml.

web.xml
<error-page>
  <error-code>404</error-code>
  <location>/WEB-INF/views/404.jsp</location>
</error-page>
<error-page>
  <error-code>500</error-code>
  <location>/WEB-INF/views/500.jsp</location>
</error-page>

Run mvn clean compile war:inplace, rerun Tomcat, and visit http://localhost:8080/admin. If the user has only the ROLE_USER privilege, /WEB-INF/views/403.jsp will be displayed.

Implementing AccessDeniedHandler

If you have business logic to perform before showing the user an error page, you should configure your access denied handler by implementing the org.springframework.security.web.access.AccessDeniedHandler.

Create a MyAccessDeniedHandler that implements AccessDeniedHandler.

MyAccessDeniedHandler.java
package net.java_school.spring;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;

public class MyAccessDeniedHandler implements AccessDeniedHandler {

  private String errorPage;

  public void setErrorPage(String errorPage) {
    this.errorPage = errorPage;
  }

  @Override
  public void handle(HttpServletRequest req, HttpServletResponse resp, AccessDeniedException e)
      throws IOException, ServletException {
    //TODO: business logic
    req.getRequestDispatcher(errorPage).forward(req, resp);
  }
}

Add the following to security.xml.

security.xml
<beans:bean id="my403" class="net.java_school.spring.MyAccessDeniedHandler">
    <beans:property name="errorPage" value="403" />
</beans:bean>

Modify the security.xml file as follows:

security.xml
<access-denied-handler ref="my403" />

The Spring Security tag does not work for error pages set in web.xml because the request is forwarded to these error pages before the view-level security filter works.

Method Security

The simplest way to map an exception to an error page in Spring MVC is to use the SimpleMappingExceptionResolver. The following configuration maps to error-403 when the org.springframework.security.access.AccessDeniedException occurs, and to error when any other exception occurs. The view resolver interprets error-403 and error as /WEB-INF/views/error-403.jsp and /WEB-INF/views/error.jsp respectively.

spring-bbs-servlet.xml
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
  <property name="defaultErrorView" value="error" />
  <property name="exceptionMappings">
    <props>
      <prop key="AccessDeniedException">
      error-403
      </prop>
    </props>
  </property>
</bean>

After signing up and logging in with janedoe@gmail.org/1111, try to withdraw membership with johndoe@gmail.org/1111 from the Bye menu.

UserService.java
@PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER') and #user.email == principal.username")
public void bye(User user);

The highlighted part above will work and occur an org.springframework.security.access.AccessDeniedException, and you will see /WEB-INF/views/error-403.jsp.

On the Bye page, try to withdraw membership with janedoe@gmail.org and the wrong password.

UserServiceImpl.java
@Override
public void bye(User user) {
  String encodedPassword = this.getUser(user.getEmail()).getPasswd();
  boolean check = this.bcryptPasswordEncoder.matches(user.getPasswd(), encodedPassword);
	
  if (check == false) {
    throw new AccessDeniedException("Wrong password!");
  }
	
  userMapper.deleteAuthority(user.getEmail());
  userMapper.delete(user);
}

The highlighted part above will occur an org.springframework.security.access.AccessDeniedException, and you will see /WEB-INF/views/error-403.jsp.

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Ошибка 403 error the request could not be satisfied
  • Ошибка 403 sip регистрация