让 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