如何使用Spring使用OAuth2保护MVC应用程序?

时间:2018-05-30 03:34:07

标签: spring-mvc spring-security-oauth2

抱歉,我的英文。

我有一个应用程序,我可以通常的方式登录。

@Configuration
@EnableWebSecurity
public class LoginSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        System.out.println("LoginSecurityConfig :: configure");

        auth.jdbcAuthentication().dataSource( getDataSource() )
            .passwordEncoder( new BCryptPasswordEncoder(16) )
            .usersByUsernameQuery(
                "select user_name as username,password,enabled from users where user_name=?")
            .authoritiesByUsernameQuery(
                "select user_name as username, role_name from users_roles ur join users u on ur.user_id = u.user_id and u.user_name = ?");

    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {


        http
        .csrf().disable()
        .authorizeRequests()
        .antMatchers("/login*").anonymous()
        .antMatchers("/resources/**").permitAll()
        .antMatchers("/fotos/**").permitAll()
        .antMatchers("/users").access("hasRole('ROLE_ADMIN')")
        .antMatchers("/user").access("hasRole('ROLE_ADMIN')")
        .anyRequest().authenticated()
        .and()

        .formLogin()
        .loginPage("/loginPage")
        .defaultSuccessUrl("/home", true)
        .failureUrl("/loginPage?error=true")
        .loginProcessingUrl("/login")
        .usernameParameter("username")
        .passwordParameter("password")
        .and()

        .logout()
        .logoutSuccessUrl("/loginPage")
        .invalidateHttpSession(true); 



    }    

}

使用此功能,我可以尝试访问任何安全资源,系统会将我发送到loginPage,我可以将usernamepassword发送到内部login控制器,然后我有Principal并且可以访问安全资源(家庭,用户,用户)。工作正常。

但是......我需要删除用户控件数据库并使用OAuth2来允许相同类型的访问。我不想再在我的数据库中拥有任何用户了。我需要一个登录屏幕,然后在http://myserver/oauth/token?grant_type=password&username=admin&password=admin中传递client_idclient_secret等令牌请求。我知道怎么做"得到令牌"部分和我的服务器工作正常,并给我令牌和刷新令牌,但只使用邮差,因为我不知道如何在我的Web应用程序代码中使用它。我发现的所有教程都在同一个应用程序中同时使用服务器和客户端,实际上并没有展示如何使用OAuth2远程服务器。

已尝试使用this。这是一个很好的教程,非常接近我的需要,但对我来说太复杂了。

我有这段代码,并了解它可以使用服务器并使用客户端凭据发出令牌,但不知道如何向用户提供登录屏幕并获取其凭据以完成请求({ {1}}部分)。

Basic

所以...我如何保护我的系统,从用户那里获取登录名和密码,并使用这段代码控制凭证,就像我使用通常的数据库方法一样?

或者OAuth2仅适用于安全的REST API?

enter image description here

请新手友好,因为我使用Spring不太舒服。

2 个答案:

答案 0 :(得分:5)

简单如1,2,3 ......

只需更改我的OAuth2服务器以接受oauth/authorize方法。

@Override
protected void configure(HttpSecurity http) throws Exception {

    http
        .requestMatchers()
        .antMatchers("/login", "/oauth/authorize")
    .and()
        .authorizeRequests()
        .anyRequest()
        .authenticated()
    .and()
        .formLogin()
        .permitAll();       
}

并创建自定义登录表单。现在所有客户端(Web应用程序)都可以登录它。

您可以在此处找到示例客户端和更多详细信息:http://www.baeldung.com/sso-spring-security-oauth2

你也可以在我的github repo上查看我的整个服务器和客户端:

https://github.com/icemagno/geoinfra/cerberus

https://github.com/icemagno/geoinfra/atlas

是在pt_BR

答案 1 :(得分:4)

我最近一直在做这个,我希望我可以说我有一个简单的答案,但我没有。我不得不首先提出这样的问题:这是Web应用程序(JSP等)或Web应用程序使用的REST API,还是移动应用程序使用的REST API等等。

这一点很重要的原因是您首先必须选择其中一个OAuth2配置文件和授权类型,它们在Spring中都有不同的要求和配置。

此外,您是尝试与第三方OAuth2身份验证提供程序(例如Facebook)集成,还是您的应用程序充当身份验证提供程序(发生登录和密码验证)和受保护资源(网页请求或API调用转到)?

所以我想我能做的最好的就是给你做一些功课:

(1)了解各种OAuth2配置文件并确定哪种配置文件最适合您的应用程序,并了解所有术语(例如,什么是客户机密码?)。

这绝对不是那些你可以在不理解它的情况下剪切和粘贴示例代码的情况之一。如果您对OAuth2的工作方式没有合理的理解,那么您将遇到很多困难。

另外:我们在这里讨论的是SECURITY,所以做一些事情而不理解它是一个非常糟糕的主意。如果你不小心,你可能认为它正在发挥作用,但实际上你会让自己对攻击敞开大门。

(2)如果您不熟悉Spring Framework Security,那么您需要有一个基本的基础来理解您正在做的事情。

(3)一旦您知道要使用哪个配置文件,请在Google搜索中使用该配置文件,例如: “Spring oauth2隐式授权”找到为该配置文件量身定制的示例。

有一些在那里开始,虽然我发现由于他们的假设和我的应用程序的细微差别,我发现我无法直接将任何示例带到我的应用程序中。

Spring参考指南也很有帮助,但未必提供您可能遇到的所有问题的所有详细信息。最后,尝试使用您的应用程序实现。

您需要一些好的工具来向您的应用发送请求(我喜欢PostMan用于此目的),因此您可以检查来回的数据。 OAuth2涉及一系列复杂的HTTP重定向,因此测试可能有点困难。

另外,请耐心等待。我认为自己是一名Spring专家,我花了几天的时间才能按照我想要的方式完成工作。请注意,实际上你最终编写的代码非常少,但是完全正确地获取少量代码是很困难的。