简体   繁体   中英

Spring security error 403 handling: login page for unauthorized, 403 error for authorized user

I have following problem with 403 error handling. This is my configuration:

Part of my spring-security.xml

<sec:http auto-config="true" use-expressions="true" entry-point-ref="ep403" disable-url-rewriting="true">
    <sec:form-login login-page="/login"
                    login-processing-url="/login"
                    username-parameter="email"
                    password-parameter="password"
    />
    <sec:access-denied-handler error-page="/errors/access-denied"/>
    <sec:logout invalidate-session="true" delete-cookies="JSESSIONID,SPRING_SECURITY_REMEMBER_ME_COOKIE"
                logout-success-url="/login"/>
    <sec:session-management session-fixation-protection="newSession"/>
</sec:http>



<bean id="ep403" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>

If logged/unauthorized user enter to link without rights to view url - he will be redirected to 403 error page and logged out from system if already logged in. I need solution which allow me to redirect logged user to 403 page & logout, but for unauthorized user i want to see login page instead of 403 error, do You know there's any chance to achieve that goal?

I try with my own AuthenticationEntryPoint implementation, I want to check user from Security Context and if its not logged in - execute different action than redirect to forbidden page, but authentication is always null in this case, because logged user on this error page is unfortunately already logged out

public class AccessDeniedEntryPoint implements AuthenticationEntryPoint {

    public void commence(HttpServletRequest request, HttpServletResponse response,
                         AuthenticationException arg2) throws IOException, ServletException {
        Authenticationauthentication = SecurityContextHolder.getContext().getAuthentication();
        response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
    }

}

On your /errors/access-denied mapping check for JSESSIONID,SPRING_SECURITY_REMEMBER_ME_COOKIE cookies. if they are null that means the user had not a successful login to have the cookies, so redirect him to login, if not let him see the access-denied page.

@RequestMapping(value="/errors/access-denied")
public String error(HttpServletRequest request) {
  Cookie[] cookies = request.getCookies();
  if (cookies != null) {
    for (Cookie cookie : cookies) {
        if (cookie.getName().equals("JSESSIONID") || 
            cookie.getName().equals("SPRING_SECURITY_REMEMBER_ME_COOKIE")) {
            return "access-denied";
        }
    }
  return "login";
 }

最后,我在 spring security 自定义过滤器中实现了这个功能

in your security config file I think you might need to add the url of you application that doesn't need or require Authentication for example .

        @Override
    protected void configure(final HttpSecurity http) throws Exception {
        // @formatter:off
        http
        .csrf().disable()
        .authorizeRequests() 
        .antMatchers("/login*",""
                + "/signin/**",""
                + "/signup/**",""
                + "/api/v1/products/**",""
                + "/api/v1/addproduct/**",""
                + "/api/v1/addCategory/**"
                ).permitAll()
        .anyRequest().authenticated()
//        .and() 
//        .formLogin().loginPage("/login").permitAll()
        .and()
        .logout();
    } // @formatter:on

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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