Spring Security : Customize 403 access denied page

In Spring Security, if non authorized user try to access a protected page, a default “http 403 access denied” will be displayed :

spring-security-403-default

In this tutorial, we will show you how to customize 403 access denied page in Spring Security.

1. Spring Security Configuration

Review a configuration, if “alex” try to access /admin page, above 403 access denied page will be displayed.

Spring-Security.xml

  <http auto-config="true">
	<access-denied-handler error-page="/403" />
	<intercept-url pattern="/admin**" access="ROLE_ADMIN" />
  </http>

  <authentication-manager>
	<authentication-provider>
	  <user-service>
		<user name="alex" password="123456" authorities="ROLE_USER" />
		<user name="mkyong" password="123456" authorities="ROLE_USER, ROLE_ADMIN" />
	  </user-service>
	</authentication-provider>
  </authentication-manager>

2. Solution – Customize 403 Page

2.1 Create a new 403 page.

403.jsp

<html>
<body>
	<h1>HTTP Status 403 - Access is denied</h1>
	<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
     style="display:block"
     data-ad-client="ca-pub-2836379775501347"
     data-ad-slot="8821506761"
     data-ad-format="auto"
     data-ad-region="mkyongregion"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script><h2>${msg}</h2>
</body>
</html>

2.2. To display above page, add a error-page like the following :

Spring-Security.xml

	<http auto-config="true">
		<access-denied-handler error-page="/403" />
		<intercept-url pattern="/admin**" access="ROLE_ADMIN" />
	</http>

2.3 In a controller class, add a mapping for “/403” url :

HelloController.java

package com.mkyong.web.controller;

import java.security.Principal;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HelloController {

	// for 403 access denied page
	@RequestMapping(value = "/403", method = RequestMethod.GET)
	public ModelAndView accesssDenied(Principal user) {

		ModelAndView model = new ModelAndView();

		if (user != null) {
			model.addObject("msg", "Hi " + user.getName() 
			+ ", you do not have permission to access this page!");
		} else {
			model.addObject("msg", 
			"You do not have permission to access this page!");
		}

		model.setViewName("403");
		return model;

	}

}

Done.

For annotation users, use this .exceptionHandling().accessDeniedPage("/403").

SecurityConfig.java

package com.mkyong.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {

	 http.authorizeRequests()
	    .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
	    .and().formLogin()
		.loginPage("/login").failureUrl("/login?error")
		.usernameParameter("username")
		.passwordParameter("password")
	    .and().logout().logoutSuccessUrl("/login?logout")
	    .and()
		.exceptionHandling().accessDeniedPage("/403")
	}
}

3. AccessDeniedHandler

In additional, you can create a custom AccessDeniedHandler to perform some business logics before pass the URL to /403 mapping.

MyAccessDeniedHandler.java

package com.mkyong.web.exception;

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 MyAccessDeniedHandler() {
	}

	public MyAccessDeniedHandler(String errorPage) {
		this.errorPage = errorPage;
	}

	public String getErrorPage() {
		return errorPage;
	}

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

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

		//do some business logic, then redirect to errorPage url
		response.sendRedirect(errorPage);

	}

}

Add a ref to http tag.

Spring-Security.xml

	<http auto-config="true">
		<access-denied-handler ref="my403" />
		<intercept-url pattern="/admin**" access="ROLE_ADMIN" />
	</http>

	<beans:bean id="my403"
		class="com.mkyong.web.exception.MyAccessDeniedHandler">
		<beans:property name="errorPage" value="403" />
	</beans:bean>

Done.

4. Demo

When “alex” try to access /admin page, above customizing 403 access denied page will be displayed.

4.1 If using error-page, url will be displayed like this :

http://localhost:8080/spring-security-403-access-denied/admin

spring-security-403-example1

4.2 If using custom access denied handler ref, url will be displayed like this :

http://localhost:8080/spring-security-403-access-denied/403

spring-security-403-example2

Download Source Code

Download it – spring-security-403-access-denied.zip (26 KB)

References

  1. StackOverflow : How to handle HTTP 403 with Spring Security 3.0.x
  2. Spring Security : AccessDeniedHandler Reference

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

Leave a Reply

avatar
newest oldest most voted
chris
Guest
chris

I used the same exceptionhandling.accessDeniedPage() method but it doesn’t work. When I try to access a 403 page, I get redirected to the login page, I think it might be because I called the formlogin() method? Do you have any idea on how to solve this?

Many thanks!

Cristin
Guest
Cristin

This is exactly the kind of HOW NOT TO tutorial. Downloaded the project, doesn’t work. The author just copy pastes some code, doesn’t explain anything and when the user tries to run the demo, he has no idea where the problem is.

cc69cc
Guest
cc69cc

How solver the follow? If you send a null credential, spring security reconize that like valid (because is not void) but in some place is going to crash!

sdgian
Guest
sdgian

How about the “return url”? How to pass the url of the resource that I want to access in the firts place once the auth process is done correctly?

xiaoyu
Guest
xiaoyu

thanks for your article, i want to display the access denied page when there is an access denied in method security level(by using the preauthorize annotation), but your method doesn’t work, could you help me find out the answer? thank you

Gary
Guest
Gary

Thanks for the article, our team is having the same problem with preauthorize, can @mkyong:disqus you please help?

Guest
Guest
Guest

It’s a error?

I changed it to

It works well, so I think whether it’s a error? Any One know?

mkyong
Guest
mkyong

Sorry for the typo, Article is updated, please get the latest source code to test. Thanks.

trackback
spring security - access-denied-handler | BlogoSfera

[…] http://www.mkyong.com/spring-security/customize-http-403-access-denied-page-in-spring-security/ access denied page using spring security not working How to redirect to access-denied-page with spring security […]

trackback
spring access-denied-handler not workingCopyQuery CopyQuery | Question & Answer Tool for your Technical Queries,CopyQuery, ejjuit, query, copyquery, copyquery.com, android doubt, ios question, sql query, sqlite query, nodejsquery, dns query, update qu

[…] http://www.mkyong.com/spring-security/customize-http-403-access-denied-page-in-spring-security/ access denied page using spring security not working How to redirect to access-denied-page with spring security […]

Radhe
Guest
Radhe

I don’t think creating handler and implementing it is good way.

You can just simply declare access deniedpage and your work done!!!!…
Thanks,
Radhe

Radhe
Guest
Radhe

Code snippet was removed. So, adding it!!!

<http auto-config="true" access-denied-page="/deniedpage"> 
mkyong
Guest
mkyong

Agreed, error-page should be enough.

IvoHaSp
Guest
IvoHaSp

Hi, is it right?

First you wrote:

The easiest way is uses “access-denied-handler‘ tag, and put your 403 page in “error-page” attribute :

but after that you mentioned 404 (a mistake?):

and correct it is:

Please, could you review attached zip file? I thing that many beginners like me have read this article they will a little disapoitmented.

Thank a lot Ivo.

mkyong
Guest
mkyong

Sorry for the typo, article is updated.

zecke
Guest
zecke

For this example you have forgot to display a controller, like this:


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

@Controller
public class ErrorController {
	@RequestMapping(value = "/403")
    public String accessDenied() {

          return "403"; // logical view name
     }

}


Please note you use a jsp-page. Without this controller you get an 404 error and a warning:
No mapping found for HTTP request with URI [/SpringMVC/403] in DispatcherServlet with name ‘mvc-dispatcher’

Bruce
Guest
Bruce

Thanks for your contribution

mkyong
Guest
mkyong

Article is updated, thanks for your inputs.

Haibin
Guest
Haibin

I think another way to do it is to define

403
/403.jsp

in web.xml and webapp/403.jsp

Haibin
Guest
Haibin
    <error-page>
        <error-code>403</error-code>
        <location>/403.jsp</location>
    </error-page>
Siddharth
Guest
Siddharth

Hello Haibin,

I have configured the webserver to display the error page where 404 is working fine but 403 is not working .

Is there any dependency in order to create 403 custom error page.I have used the below line to create custom error page

ErrorDocument 404 /404-page.html
ErrorDocument 403 /403-page.html

Waiting for your revert.

Regards,
Siddharth

Indravadan
Guest
Indravadan

Please changes the follwoing:

Without “/” against the 404, got the error.

trackback
Spring Security access control example

[…] “ROLE_ADMIN“. Customize 403 page Default 403 page is ugly, read this example – How to customize http 403 access denied page in spring security.Download Source Code Download it – Spring-Security-Access-Control-Example.zip (10 […]