Spring安全登录错误页面,访问被拒绝

Posted

技术标签:

【中文标题】Spring安全登录错误页面,访问被拒绝【英文标题】:Spring security login error page, access denied 【发布时间】:2018-07-11 15:04:39 【问题描述】:

当我使用无效凭据登录到受 oauth2 保护的表单时,重定向到默认登录错误页面“login?error”不起作用。在我的日志中我可以看到:

2018-02-01 10:58:35.935 DEBUG 17600 --- [http-nio-8899-exec-8] w.a.UsernamePasswordAuthenticationFilter : Updated SecurityContextHolder to contain null Authentication
2018-02-01 10:58:35.935 DEBUG 17600 --- [http-nio-8899-exec-8] w.a.UsernamePasswordAuthenticationFilter : Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@49d1bcfd
2018-02-01 10:58:35.935 DEBUG 17600 --- [http-nio-8899-exec-8] .a.SimpleUrlAuthenticationFailureHandler : Redirecting to /login?error
2018-02-01 10:58:35.935 DEBUG 17600 --- [http-nio-8899-exec-8] o.s.s.web.DefaultRedirectStrategy        : Redirecting to '/uaa/login?error'

但在重定向后出现“拒绝访问”异常:

2018-02-01 10:58:35.943 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /login?error=; Attributes: [authenticated]
2018-02-01 10:58:35.943 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.a.i.FilterSecurityInterceptor    : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@6fa90ed4: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@fffc7f0c: RemoteIpAddress: 127.0.0.1; SessionId: 03550F34462ABD6D42B5E224A4C478F9; Granted Authorities: ROLE_ANONYMOUS
2018-02-01 10:58:35.943 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@337e3785, returned: -1
2018-02-01 10:58:35.943 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.a.ExceptionTranslationFilter     : Access is denied (user is anonymous); redirecting to authentication entry point

org.springframework.security.access.AccessDeniedException: Access is denied

然后再次重定向到登录页面'/login'

2018-02-01 10:58:35.943 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.util.matcher.AndRequestMatcher   : Trying to match using Ant [pattern='/**', GET]
2018-02-01 10:58:35.943 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request '/login' matched by universal pattern '/**'
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.util.matcher.AndRequestMatcher   : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/**/favicon.ico']]
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login'; against '/**/favicon.ico'
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.matcher.NegatedRequestMatcher  : matches = true
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.util.matcher.AndRequestMatcher   : Trying to match using NegatedRequestMatcher [requestMatcher=MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@27122376, matchingMediaTypes=[application/json], useEquals=false, ignoredMediaTypes=[*/*]]]
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher      : httpRequestMediaTypes=[text/html, application/xhtml+xml, image/webp, image/apng, application/xml;q=0.9, */*;q=0.8]
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher      : Processing text/html
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher      : application/json .isCompatibleWith text/html = false
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher      : Processing application/xhtml+xml
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher      : application/json .isCompatibleWith application/xhtml+xml = false
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher      : Processing image/webp
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher      : application/json .isCompatibleWith image/webp = false
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher      : Processing image/apng
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher      : application/json .isCompatibleWith image/apng = false
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher      : Processing application/xml;q=0.9
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher      : application/json .isCompatibleWith application/xml;q=0.9 = false
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher      : Processing */*;q=0.8
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher      : Ignoring
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.m.MediaTypeRequestMatcher      : Did not match any media types
2018-02-01 10:58:35.944 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.matcher.NegatedRequestMatcher  : matches = true
2018-02-01 10:58:35.948 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.util.matcher.AndRequestMatcher   : Trying to match using NegatedRequestMatcher [requestMatcher=RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]]
2018-02-01 10:58:35.948 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.u.matcher.NegatedRequestMatcher  : matches = true
2018-02-01 10:58:35.948 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.util.matcher.AndRequestMatcher   : All requestMatchers returned true
2018-02-01 10:58:35.948 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.s.HttpSessionRequestCache        : DefaultSavedRequest added to Session: DefaultSavedRequest[http://localhost:8765/uaa/login?error=]
2018-02-01 10:58:35.948 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.w.a.ExceptionTranslationFilter     : Calling Authentication entry point.
2018-02-01 10:58:35.948 DEBUG 17600 --- [http-nio-8899-exec-10] o.s.s.web.DefaultRedirectStrategy        : Redirecting to 'http://localhost:8765/uaa/login'

有人知道出了什么问题吗?

编辑:添加安全配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Order(-20)
protected static class LoginConfig extends WebSecurityConfigurerAdapter 
    ...
    @Override
    public void configure(WebSecurity web) throws Exception 
        web.ignoring().antMatchers("/static/**", "/images/**", "/fonts/**", "/health", "/info");
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        // @formatter:off
        http
            .authorizeRequests()
                .antMatchers("/console/**", "/reset").permitAll()
            .and()
                .formLogin()
                .loginPage("/login")
                .permitAll()
            .and()
                .requestMatchers()
                .antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access", "/reset")
            .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated();
        // @formatter:on
    

另一个编辑:当我直接访问 oauth2 服务器而不通过 Zuul 时,重定向到登录错误页面 'login?error' 页面有效。

Zuul的安全配置是

   @Override
public void configure(HttpSecurity http) throws Exception 
    // @formatter:off
    http
        .logout()
        .permitAll()
        .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK))
    .and()
        .authorizeRequests()
        .antMatchers("/uaa/**", "/login", "/xxx/view3/**", "/*/view404", "/*/view403").permitAll()
    .and()
        .authorizeRequests()
        .antMatchers("/xxx/**/*").hasAnyRole("USER", "ADMIN")
        .antMatchers("/yyy/**/*").hasRole("ADMIN")
    .and()
        .authorizeRequests().anyRequest().authenticated()
    .and()
        .csrf().requireCsrfProtectionMatcher(csrfRequestMatcher()).csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
    .and()
        .exceptionHandling()
        .accessDeniedHandler(accessDeniedHandler());
    // @formatter:on

编辑:添加请求跟踪

从 Chrome DEV-Tools 导出 HAR:Just share it

只需将其粘贴到此处以进行可视化:HAR viewer

【问题讨论】:

重定向日志来自 Oauth2 服务器。 我所说的 Oauth2 服务器是指同时充当授权服务器和资源服务器的服务(称为 uaa-service)。上下文路径是/uaa,正确。我的设置类似于 github.com/kakawait/uaa-behind-zuul-sample/blob/master/… 所以 Zuul 会转发请求。 URL 之间的唯一区别是端口:Zuul:localhost:8765/uaa/loginUAA:localhost:8899/uaa/login 是的,localhost:8765/uaa/login?error 重定向到 /login localhost:8899/uaa/login?error 会显示错误消息,如果存在查询字符串“error”,则会解析该错误消息。 【参考方案1】:

解决办法是添加

.antMatchers("/console/**", "/reset", "/login").permitAll()

到 uaa-service 的 WebSecurityConfigurerAdapter。最终工作配置

@Override
    protected void configure(HttpSecurity http) throws Exception 
        // @formatter:off
        http
            .authorizeRequests()
                .antMatchers("/console/**", "/reset", "/login").permitAll()
            .and()
                .formLogin()
                .loginPage("/login")
                .permitAll()
            .and()
                .requestMatchers()
                .antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access", "/reset")
            .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated();
        // @formatter:on
    

如果有人能解释为什么这是必要的,那就太好了。

【讨论】:

哦,也许我看到了问题所在。 Zuul 将= 添加到重定向 URL:/login?error=。它应该只是/login?error。添加antMatcher 模式有效,因为它会忽略任何查询字符串。 那么您认为这是 Zuul 中的错误还是我这边的一些配置错误?感谢您的时间和支持。

以上是关于Spring安全登录错误页面,访问被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

jsf spring安全访问被拒绝认证登录

Spring security hasRole() 给出错误 403 - 访问被拒绝

在struts2中使用spring security总是显示访问被拒绝页面

在 Spring Security 中启用 CSRF 时,访问被拒绝 403

使用 Spring 连接远程数据库的访问被拒绝错误

Symfony2 - 访问被拒绝