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

Mag*_*o C 10 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); 



    }    

}
Run Code Online (Sandbox Code Playgroud)

使用这个我可以尝试访问任何安全资源,系统将我发送到loginPage我可以发布的地方username和password内部login控制器然后我有,Principal并且可以访问安全资源(家庭,用户,用户).工作正常.

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

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

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

@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfigRemoteTokenService extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(final HttpSecurity http) throws Exception {
                http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                    .and()
                    .authorizeRequests().anyRequest().permitAll();              
    }

    @Primary
    @Bean
    public RemoteTokenServices tokenServices() {
        final RemoteTokenServices tokenService = new RemoteTokenServices();
        tokenService.setCheckTokenEndpointUrl("http://myoauthserver/oauth/check_token");
        tokenService.setClientId("clientid");
        tokenService.setClientSecret("password");
        return tokenService;
    }

}
Run Code Online (Sandbox Code Playgroud)

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

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

在此输入图像描述

请新手友好,因为我不太习惯使用Spring.

小智 6

我最近自己一直在研究这个,我希望我能说我有一个简单的答案,但我没有。我必须首先问这样的问题,这是一个 Web 应用程序(JSP 等)还是一个 Web 应用程序使用的 REST API,或者一个移动应用程序使用的 REST API,等等。

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

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

所以我想我能做的最好的事情就是给你分配一些家庭作业:

(1) 阅读各种 OAuth2 配置文件并确定哪一个最适合您的应用程序,并学习所有术语(例如,什么是客户端机密?)。

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

另外:我们在这里谈论安全,所以在不了解的情况下做事是一个非常糟糕的主意。如果您不小心,您可能会认为它有效,但实际上您让自己很容易受到攻击。

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

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

那里有一些,这是一个很好的起点,尽管我发现我无法将任何示例直接带到我的应用程序中,因为它们的假设和我的应用程序之间存在细微差别。

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

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

另外,要有耐心。我认为自己是 Spring 专家,但我仍然花了几天时间才能让事情完全按照我想要的方式工作。请注意,实际上您最终编写的代码非常少,但是让少量代码完全正确是很困难的。


Mag*_*o C 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();       
}
Run Code Online (Sandbox Code Playgroud)

并创建自定义登录表单.现在所有客户端(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中