简体   繁体   中英

Spring security default login form disappears when adding WebSecurityConfigurerAdapter

I have a Spring Boot 2 application with some controllers.
I wat to add Spring Security and allow some urls for only authenticated users, whereas others should be accessible for all.
But when I use WebSecurityConfigurerAdapter to configure cecurity per-url, auto-generated pages for "/login" and "/error" disappear .

If I try to add the simplest possible configuration, it works and protects all urls:

application.yml

spring:
  security:
    user:
      name: "admin"
      password: "1234"
      roles: "ADMIN"

pom.xml :

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

And every action redirects me to /login page with login form, until I log in with credentials I configured.

However, If I add a configuration class to customize the behavior, the default login form seems to be missing, and I keep getting /error page instead because there is no such resource as /login :

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .inMemoryAuthentication()
                .withUser("admin").password("1234").roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/private").hasRole("ADMIN")
                .antMatchers("/public").permitAll()
                .antMatchers("/", "/login", "/logout", "/error").permitAll()
                .antMatchers("/**").denyAll();
    }
}

Here are some debug logs (the rest is omitted for readability):

DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@e4de2840: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
...
DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : '/login'; against '/login'
DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /login; Attributes: [permitAll]
DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@e4de2840: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@2a3c0a9c, returned: 1
DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful
DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object
DEBUG o.s.security.web.FilterChainProxy - /login reached end of additional filter chain; proceeding with original chain
DEBUG o.s.web.servlet.DispatcherServlet - GET "/login", parameters={}
DEBUG o.s.w.s.h.SimpleUrlHandlerMapping - Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
DEBUG o.s.o.j.s.OpenEntityManagerInViewInterceptor - Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
DEBUG o.s.w.s.r.ResourceHttpRequestHandler - Resource not found
DEBUG o.s.s.w.h.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@27581ee6
DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
DEBUG o.s.o.j.s.OpenEntityManagerInViewInterceptor - Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
DEBUG o.s.web.servlet.DispatcherServlet - Completed 404 NOT_FOUND
DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
DEBUG o.s.security.web.FilterChainProxy - /error at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
...
DEBUG o.s.security.web.FilterChainProxy - /error reached end of additional filter chain; proceeding with original chain
DEBUG o.s.web.servlet.DispatcherServlet - "ERROR" dispatch for GET "/error", parameters={}
DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)
DEBUG o.s.o.j.s.OpenEntityManagerInViewInterceptor - Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
DEBUG o.s.w.s.v.ContentNegotiatingViewResolver - Selected 'text/html' given [text/html, text/html;q=0.8]
DEBUG o.s.o.j.s.OpenEntityManagerInViewInterceptor - Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
DEBUG o.s.web.servlet.DispatcherServlet - Exiting from "ERROR" dispatch, status 404
DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed

At the end I get error page in browser, saying that there is no /error page either.

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Tue Jan 21 14:53:17 CET 2020
There was an unexpected error (type=Not Found, status=404).
Not Found

For some reason, auto-generated pages for "/login" and "/error" disappear when I use WebSecurityConfigurerAdapter configuration class. Where are they gone?

Moreover, this Previously Authenticated: looks suspicious to me, because It was a fresh app start. But if I try to disable anonymous users with http.anonymous().disable() , I start getting 403 error for any url. Can it be related?

You are missing: .formLogin().loginPage("/login")

Something like:

 http
        .authorizeRequests()
        .antMatchers("/private").hasRole("ADMIN")
        .antMatchers("/public").permitAll()
        .antMatchers("/", "/login", "/logout", "/error").permitAll()
        .antMatchers("/**").denyAll()
        .and().formLogin().loginPage("/login");
.and().formLogin().loginPage("/login");

Above would require a custom designed login page. If you want to use Spring security's default login page then just add below

.and().formLogin()

That's all

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