首页 > 解决方案 > 通过 MultiHttpSecurityConfig 实现“oauth2Login()”和“httpBasic()”同一页面

问题描述

如果用户点击/api/*,会加载“formLogin()”页面;否则加载“httpBasic()”。此设置工作正常。下面是它的代码。

@Configuration
    public class SecurityConfig {

    @Configuration
    @Order(1)
    public static class SpecialSecurityConfig extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .antMatcher("/api/**")
                .authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                .formLogin()
                    .loginPage("/api/login");         
        }
        
        @Override
        public void configure(WebSecurity web) throws Exception {
          web.ignoring().antMatchers("/", "/css/**");
        }
    }

    @Configuration
    public static class RegularSecurityConfig extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                .httpBasic();
        }
        
        @Override
        public void configure(WebSecurity web) throws Exception {
          web.ignoring().antMatchers("/", "/css/**");
        }
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user")
                .password("{noop}pass")
                .roles("USER");
    }
}

现在我想删除“formLogin()”并将其替换为“oauth2Login()”。之后,当我单击 google 链接时,它会加载“httpBasic()”登录页面。如果用户点击谷歌,它应该去谷歌登录页面。请帮我解决这个问题。下面是它的代码。

    http
    .antMatcher("/api/**")
    .authorizeRequests()
    .anyRequest().authenticated()
    .and()
    .oauth2Login()
    .loginPage("/api/oauth_login")
    .permitAll();

oauth_login.html

<body>
<div class="container">
<h1>Social Login</h1>
<p><a href="/oauth2/authorization/google">Google</a></p>
</div>
</body>

标签: spring-bootspring-securityoauth-2.0google-oauthspring-security-oauth2

解决方案


您指定应该使用 OAuth 2 登录"/api/**"来保护匹配的请求,并且应该使用 HTTP 基本SpecialSecurityConfig来保护所有其他请求。RegularSecurityConfig

由于"/oauth2/authorization/google"不匹配"/api/**",因此使用 HTTP basic 对其进行保护。

一种选择是更改用于授权请求的基本 URI "/api/"(默认为"/oauth2/authorization/{registrationId}")。

您可能还想自定义loginProcessingUrlauthorizationRequestResolver

public void configure(HttpSecurity http) throws Exception {
    http
        .antMatcher("/api/**")
        .authorizeRequests(authorize -> authorize
            .anyRequest().authenticated()
        )
        .oauth2Login(oauth2 -> oauth2
            .loginProcessingUrl("/api/login/oauth2/code/*")
            .loginPage("/api/oauth_login")
            .authorizationEndpoint(ae -> ae
                .baseUri("/api/oauth2/authorization/{registrationId}")
                .authorizationRequestResolver(getAuthorizationRequestResolver())
            )
        );
}

private OAuth2AuthorizationRequestResolver getAuthorizationRequestResolver() {
    return new DefaultOAuth2AuthorizationRequestResolver(
        this.clientRegistrationRepository,
        "/api/oauth2/authorization");
}

然后,您还将更新您的登录表单

<p><a href="/api/oauth2/authorization/google">Google</a></p>

推荐阅读