spring-security - Spring Security OAuth2 redirect_uri 回调结果为 404

标签 spring-security google-oauth

我正在尝试编写一个允许通过 JDBC 或 Google/Facebook 进行身份验证的网络应用程序;使用 Spring Security 5.0.x。我有有效的 Google 客户端 ID 和密码。 OAuth2 网络流程正确地将我带到 Google 以进行帐户选择和同意,但对 redirect_uri 的回调失败并显示 404。我看不出我做错了什么。

@Configuration
@EnableScheduling
@EnableWebSecurity
public class WebSecurityConfig
    extends WebSecurityConfigurerAdapter
{
    private static final Logger _logger = LogManager.getLogger (WebSecurityConfig.class);

    private static String
        SuccessUrl = "/api/auth/login-success",
        FailureUrl = "/api/auth/login-failure",
        LogoutUrl = "/api/auth/logout-done";

    private static String
        PGoogleId = "oauth2.google.id",
        PGoogleSecret = "oauth2.google.secret",
        PFacebookId = "oauth2.facebook.id",
        PFacebookSecret = "oauth2.google.secret";

    private final List<ClientRegistration> _regns;

    @Autowired
    private AuthSuccessHandler _success;
    @Autowired
    private AuthFailureHandler _failure;
    @Autowired
    private DataSource _source;
    @Autowired
    private MezoUserManager _userManager;

    /**
     * Sole Constructor
     */
    public WebSecurityConfig ()
    {
        _regns = new ArrayList<> ();
    }

    @Autowired
    public void setPropertiesFactory (
        PropertiesFactoryBean factory)
        throws IOException, AddressException
    {
        Properties p = factory.getObject ();
        extractIdSecret (CommonOAuth2Provider.GOOGLE.getBuilder ("google"), PGoogleId, PGoogleSecret, p);
        extractIdSecret (CommonOAuth2Provider.FACEBOOK.getBuilder ("facebook"), PFacebookId, PFacebookSecret, p);
    }

    private void extractIdSecret (
        ClientRegistration.Builder builder,
        String idKey,
        String secretKey,
        Properties properties)
    {
        String id = properties.getProperty (idKey);
        String secret = properties.getProperty (secretKey);
        if (StringUtils.isBlank (id) || StringUtils.isBlank (secret))
            return;
        _regns.add (builder.clientId (id).clientSecret (secret).build ());
    }

    @Override
    protected void configure (
        HttpSecurity http)
        throws Exception
    {
        _success.setUrl (SuccessUrl);
        _failure.setUrl (FailureUrl);

        JdbcTokenRepositoryImpl repo = new JdbcTokenRepositoryImpl ();
        repo.setDataSource (_source);

        http
            .authorizeRequests ()
                .antMatchers ("/api/profile/**").authenticated ()
                .antMatchers ("/api/users/**").hasAuthority (Authority.ROLE_ADMIN.name ())
            .antMatchers ("/api/**").permitAll ()
            .and ()
            .exceptionHandling ()
                .authenticationEntryPoint (new Http403ForbiddenEntryPoint())
                .and ()
            .formLogin ()
                .loginProcessingUrl ("/login")
                .loginPage ("/")
                .successHandler (_success)
                .failureHandler (_failure)
                .and ()
            .logout ()
                .logoutUrl ("/logout")
                .logoutSuccessUrl (LogoutUrl)
                .and ()
            .rememberMe ()
                .tokenRepository (repo)
                .tokenValiditySeconds (1209600)
                .rememberMeParameter ("remember-me")
                .and ()
            .csrf ().disable ();

        if (!_regns.isEmpty ())
        {
            http.oauth2Login ()
                .clientRegistrationRepository (new InMemoryClientRegistrationRepository (_regns));
            _logger.debug ("OAuth2 entabled");
        }
    }

    @Override
    protected void configure (
        AuthenticationManagerBuilder builder)
        throws Exception
    {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider ();
        provider.setUserDetailsService (_userManager);
        provider.setPasswordEncoder (encoder ());

        builder.authenticationProvider (provider);
        builder.userDetailsService (_userManager);
    }

    @Bean
    public BCryptPasswordEncoder encoder ()
    {
        return new BCryptPasswordEncoder ();
    }
}

来自 Google 的回调将转到正确的位置:

http://localhost:8080/mezo/login/oauth2/code/google?state=.....

但是我的 webapp 提示:

HTTP Status 404 - /mezo/login

谁能看到我在配置中遗漏了什么?为什么 Spring Security 没有自动为回调 uri 设置过滤器?

请注意,使用 JDBC 的登录当前适用于此配置。

最佳答案

解决方法是对 antMatchers() 放宽一点。特别是,扩展:

        .antMatchers ("/api/**").permitAll ()

与:

        .antMatchers ("/api/**", "/login/**").permitAll ()

关于spring-security - Spring Security OAuth2 redirect_uri 回调结果为 404,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51346388/

相关文章:

java - Spring 安全 : programmatically log in

python - 使用云存储时在 dev_appserver 上获取访问 token RefreshError 'invalid_grant'

javascript - 使用 Passport 进行谷歌身份验证: Unable to force the user to pick an account again when he tries to sign-in after the first time

java - 如何在使用服务帐户时在我的 youtube/google 帐户下上传视频文件

authentication - YouTube 直播 API 请求与 Api key

java - 实现 CQRS 模式时如何使用 Spring 处理 JWT 身份验证?

java - 在 Spring 中导入安全库时遇到问题

grails - Grails Spring Security Rest-覆盖 token

mysql - 使用主数据库在 Spring MVC 应用程序中实现 Multi-Tenancy ?

javascript - 单流: sign user in via Google oAuth AND grant offline/server access?