防止 Spring OAuth2 自动重定向

问题描述 投票:0回答:1

我正在尝试遵循 Spring Boot OAuth2 示例,遗憾的是它似乎有点过时了。本文介绍了一个简单的 Spring Boot 应用程序,该应用程序将登录外包给 OAuth 2.0 身份验证提供程序,在本例中为 GitHub。现在,一旦 pom.xml 获得新的依赖项

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>

以及

github
 中相应的 
application.yml

设置
spring:
  application:
    name: MyTestApp
  security:
    oauth2:
      client:
        registration:
          github:
            clientId: 983rkjhsaf809faj3
            clientSecret: 0af98s09gdf8sj3l5rjadsf98a7fdvdsaf

行为发生变化,调用

http://localhost:8080
自动重定向到 GitHub OAuth 2.0 登录页面。登录后,重定向会将用户发送回
http://localhost:8080
作为登录用户,显示项目中定义的
index.html
的内容。

到目前为止这还不错,但也许未登录的用户也应该可以查看

http://localhost:8080
的根目录,即
"/"
。将它们发送到GitHub登录页面将是错误的。因此,本文提出用类
WebSecurityConfigurerAdapter
来扩展代码,而当前 Spring Security 版本 6.4.1 中已经不存在该类了。我猜显示的示例适用于 Spring Security 5(?)。

因此,我尝试使用SecurityFilterChain

新方式
添加安全配置。

@Configuration
public class SecurityConfiguration {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/", "/error", "/webjars/**").permitAll()
                .anyRequest().authenticated()
            )
            .exceptionHandling(e -> e
                .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
            )
            .oauth2Login((oauth2Login) -> oauth2Login
                .userInfoEndpoint((userInfo) -> userInfo
                    .userAuthoritiesMapper(grantedAuthoritiesMapper())
                )
            );
        return http.build();
    }

    private GrantedAuthoritiesMapper grantedAuthoritiesMapper() {
        return (authorities) -> {
            Set<GrantedAuthority> mappedAuthorities = new HashSet<>();

            authorities.forEach((authority) -> {
                GrantedAuthority mappedAuthority;

                if (authority instanceof OAuth2UserAuthority) {
                    OAuth2UserAuthority userAuthority = (OAuth2UserAuthority) authority;
                    mappedAuthority = new OAuth2UserAuthority("OAUTH2_USER", userAuthority.getAttributes());
                } else {
                    mappedAuthority = authority;
                }

                mappedAuthorities.add(mappedAuthority);
            });

            return mappedAuthorities;
        };
    }
}

这里我明确地用

permitAll()
声明“/”,这应该是“指定任何人都允许的URL。”因此,我不希望Spring将用户重定向到GitHub登录页面。但确实如此!文章还建议添加一个
.exceptionHandling(...)
方法并在调用时发送
UNAUTHORIZED
。但现在我打电话给
HTTP ERROR 401
时总是得到
http://localhost:8080

我想要实现的目标很简单:

  • 我希望用户始终能够调用
    http://localhost:8080
    (因此,指向“/”),无论是否登录。
  • 如果用户调用除为
    permitAll()
    定义的 URL 之外的任何 URL,我希望他们获得
    HTTP ERROR 401

我怎样才能做到这一点?安全过滤器链的哪一部分扰乱了这个想法?

java spring spring-boot spring-security oauth-2.0
1个回答
0
投票

访问

http://localhost:8080
时,由于我们没有为
/
定义映射请求,所以请求匹配到
WelcomePageHandlerMapping
,就会转发到
/index.html
,而
/index.html
无法通过安全过滤器,除非同时添加它允许像这样:

 .requestMatchers("/", "/error", "/webjars/**", "/index.html").permitAll()
© www.soinside.com 2019 - 2024. All rights reserved.