【问题标题】:Spring Security: how to recognize, in a public page, that a user is authenticatedSpring Security:如何在公共页面中识别用户已通过身份验证
【发布时间】:2021-08-13 13:22:02
【问题描述】:

我有一个简单的 Spring Boot Web 应用程序,由 2 个页面组成:

  • 网址为https://example.com/ 的主页(可免费访问)
  • 网址为https://example.com/secure/page.html 的安全页面(需要登录才能访问)

在主页中,我正在打印访问用户的名字(如果他/她已经通过身份验证)或说明该页面由匿名用户访问的句子。

就身份验证而言,我正在使用 Keycloak。

这里是 Spring Security 配置:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
    .authorizeRequests()
    .antMatchers("/secure/**")
    .authenticated()
    .and()
    .csrf().requireCsrfProtectionMatcher(keycloakCsrfRequestMatcher())
    .and()
    .sessionManagement()
    .sessionAuthenticationStrategy(sessionAuthenticationStrategy())
    .and()
    .addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
    .addFilterBefore(keycloakAuthenticationProcessingFilter(), BasicAuthenticationFilter.class)
    .addFilterBefore(keycloakAuthenticatedActionsFilter(), BasicAuthenticationFilter.class)
    .addFilterAfter(keycloakSecurityContextRequestFilter(), SecurityContextHolderAwareRequestFilter.class)
    .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
    .and()
    .logout()
    .addLogoutHandler(keycloakLogoutHandler())
    .logoutUrl("/sso/logout").permitAll()
    .logoutSuccessUrl("/");
}

如果用户已经通过身份验证,问题是主页显示他是匿名的,因为Principal 始终是null

但是,如果用户在返回主页时进入安全页面(并且 Keycloak 允许他进入,因为他已经过身份验证),则该页面包含 - 正确 - 他的名字。

我的配置哪里错了?

似乎 Spring Security 不会检查非安全页面上的身份验证。有没有办法告诉 Spring Security 检查每个页面(安全和非安全)?

提前感谢您的支持。

【问题讨论】:

    标签: spring-boot authentication spring-security keycloak


    【解决方案1】:

    解决此问题的方法是将/** 添加到安全上下文/处理中(使用permitAll())。

    艺术就是正确地去做:

    所以在这种情况下:

     http
      .authorizeRequests()
      .antMatchers("/secure/**").authenticated()
      .antMatchers("/**").pernmitAll()
      .and()...
    

    ...应该在“允许的区域”中填写(匿名)Principal(即/**(!) ...并离开secure/**受限!;)。


    对于核心/标题问题(一旦填满校长),我认为答案已经给出:

    ..如果你使用Spring Security (JSP) TaglibsisAnonymous()很方便,否则(默认情况下)你只需要检查hasRole('ROLE_ANONYMOUS')Ref

    【讨论】:

    • 感谢您的宝贵建议。我实施了建议的解决方案,实际上,Principal 现在填充了ROLE_ANONYMOUS 并且不再为空。然而,这不是问题的解决方案,因为如果已经登录的用户访问主页(公共),则在他进入安全页面之前,它将被识别为anonymous。从此,他得到了应有的认可。如果 .permitAll() 存在,Spring Security 似乎不会检查 SSO 系统。我还能尝试什么?非常感谢您的支持。
    • sry,如果我没看错,但是当他“进入主页”时,他是如何“登录”的?有点像鸡蛋的问题!? (我倾向于鸡蛋;)...是的,使用此解决方案,您只能匿名或经过身份验证....并且由于您只需要在安全区域(根据要求)进行身份验证,因此每个“进入”家庭的用户页面将是匿名的!...直到他(访问安全区域并)登录...(然后返回主页,以他的名字欢迎他;)
    • 虽然,我是 xerx593,化身......我不能指望任何网站在我登录之前知道这一点......(这可以通过“cookie”实现)...... .
    • 用户已通过身份验证,因为他登录了 SSO 系统下的另一个应用程序。所以,我希望当他到达主页时,Spring Security 能够立即识别他,而无需进入安全页面(一切都按预期工作)。非常感谢您的时间。
    • 谢谢,现在对我来说更有意义了!是的,这听起来像:SSO 未正确配置/主体不会被填充... ... -> baeldung.com/… ;)
    猜你喜欢
    • 2020-11-04
    • 2020-02-23
    • 2019-12-26
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 2017-08-05
    • 1970-01-01
    • 2012-03-06
    相关资源
    最近更新 更多