让 oauth2 与 spring-boot 和 rest 一起工作

Posted

技术标签:

【中文标题】让 oauth2 与 spring-boot 和 rest 一起工作【英文标题】:Getting oauth2 to work with spring-boot and rest 【发布时间】:2014-03-11 22:18:26 【问题描述】:

我试图让 oauth2 与 spring-boot 一起工作并保护我的 rest 方法调用,但没有取得很大成功。 我尝试使用 spring-security-oauth2-javaconfig:1.0.0.CI-SNAPSHOT 和 rg.springframework.boot:spring-boot-starter-security:1.0.0.RC1。

*分级: compile("org.springframework.boot:spring-boot-starter-security:1.0.0.RC1")

compile ('org.springframework.security.oauth:spring-security-oauth2-javaconfig:1.0.0.CI-SNAPSHOT')
    exclude module: 'spring-security-config'
    exclude module: 'spring-security-core'
    exclude module: 'spring-security-web'

现在我只是想让身份验证和资源服务器正常工作。我已复制并尝试修改 spring-security-oauth2-javaconfig 示例中的现有 sparklr2 示例。

我得到的最后一个错误是:"error":"invalid_client","error_description":"Bad client credentials 当我运行 curl -v --data "grant_type=password&username=marissa&password=koala&client_id=tonr&secret=secret" -X POST localhost:8100/oauth/token 时。

我从初学者的角度理解 oauth2,而关于 oauth2 和 spring-boot 和 rest 的资源匮乏使得它很难。有什么建议吗?

如果有人可以提供类似食谱的方法来配置 oauth2 身份验证和授权以保护 rest api 调用以及相关的 curl 命令,那就太棒了。,

【问题讨论】:

【参考方案1】:

对 oauth2 的 Java 配置支持正在进行中,但使用 my fork 可能会更成功。如果我是你,我现在会坚持使用 XML 来获取 oauth2 位。这是一个带有最少 XML 的bootified sparklr2。我最近没有检查它是否可以正常工作,但是如果您将启动依赖项更新为 1.0.0.RC2,它应该不会出现问题。

更新:@Configuration 的东西已经移到了主要的 OAuth2 repo,所以 fork 和它的 parent 现在基本上是多余的(并且可能很快就会被删除)。

更新:启动后的示例现在也使用@Configuration

【讨论】:

你好戴夫,当我点击分叉时,我得到一个 404。 嗨,David,我从分叉的 repo 中检查了文件并尝试进行 gradle build.. (spring-security-oauth-javaconfig.git\branches\feature\admin)。所有的单元测试都失败了,其中大多数带有 NoClassDefFoundError。我找对地方了吗? 请忽略 gradle 构建并使用 Maven。 嗨,David,我构建了 spring-security-oauth2-javaconfig 2.0.0 SNAPSHOT 并将其部署到我的本地 maven 存储库。将示例 sparklr java 和资源文件原样复制到新项目中。添加了一个主类来启动应用程序(SpringApplication.run(RestMain.class)),因为我想与嵌入式码头的独立运行相同。它编译但在启动时失败:java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling 我帮不了你。我在eclipse中从tomcat运行它,它工作正常。【参考方案2】:

是的。这就是我为使其以这种方式工作所做的工作。我相信这是正确的解决方案(除了将 client_credentials 用于grant_type,但我不是专家:-) 如果有更好的解决方案会很棒。非常感谢您花时间帮助我。


import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.config.annotation.authentication.configurers.InMemoryClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.OAuth2ServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.OAuth2ServerConfigurer;
import org.springframework.security.oauth2.provider.token.InMemoryTokenStore;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends OAuth2ServerConfigurerAdapter 

    private final String applicationName = "restservice";

    @Value("$client_id")
    private String client_id;

    @Value("$client_secret")
    private String client_secret;

    @Value("$grant_type")
    private String grant_type;

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
            .requestMatchers()
            .and()
            .authorizeRequests()
                .antMatchers("/").permitAll()
                .anyRequest().authenticated()
                .and()
            .apply(new OAuth2ServerConfigurer())
            .tokenStore(new InMemoryTokenStore())
            .resourceId(applicationName);
    

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth
            .userDetailsService(new InMemoryUserDetailsManager(getUserDetails()))
            .and()
            .apply(new InMemoryClientDetailsServiceConfigurer())
                .withClient(client_id)
                .resourceIds(applicationName)
                .scopes("read", "write")
                .authorities("USER")
                .authorizedGrantTypes(grant_type)
                .secret(client_secret);
    

    private static final Collection<UserDetails> getUserDetails() 
        List<UserDetails> userDetails = new ArrayList<UserDetails>();
        userDetails.add(new User("user", "password", AuthorityUtils.createAuthorityList(
                        "USER", "read", "write")));
        return userDetails;
    


【讨论】:

如果这对你有用,那就太好了。不过,我仍在大量重构这些东西,因此它可能会在 Spring OAuth 2.0 发布之前中断,即使没有,它最终也可能不是最好的解决方案。

以上是关于让 oauth2 与 spring-boot 和 rest 一起工作的主要内容,如果未能解决你的问题,请参考以下文章

使用 Twitch 进行身份验证时的 Spring-Boot OAuth2 奇怪行为

使用 spring-boot OAuth2 服务器保护的 Spring-boot 应用程序

将 OAuth2 添加到 spring-boot 时出现 CSRF-token 错误

如何使用spring-boot 1.3.0.RC1为oauth2提供自定义安全性配置

Spring-boot OAuth2 实现:NoSuchBeanDefinitionException:没有 AuthenticationManager 类型的合格 bean

如何将 spring security 与 rest oauth2 服务和 spring social 集成?