Spring boot 2.0 整合 oauth2 SSO

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring boot 2.0 整合 oauth2 SSO相关的知识,希望对你有一定的参考价值。

参考技术A 在一个公司中,肯定会存在多个不同的应用,比如公司的OA系统,HR系统等等,如果每个系统都用独立的账号认证体系,会给用户带来很大困扰,也给管理带来很大不便。所以通常需要设计一种统一登录的解决方案。比如我登陆了OA系统账号,进入HR系统时发现已经登录了,进入公司其他系统发现也自动登录了。使用SSO解决效果是一次输入密码多个应用都可以识别在线状态。

login.html 效果图:

home.html 效果图

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

【中文标题】让 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 发布之前中断,即使没有,它最终也可能不是最好的解决方案。

以上是关于Spring boot 2.0 整合 oauth2 SSO的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 2.0 整合Thymeleaf 模板引擎

Spring Boot 2.0 整合 ES 5 文章内容搜索实战

Spring Boot 2:Spring Boot 2.0新特性

Spring Boot Security OAuth2 实现支持JWT令牌的授权服务器

OAuth 2.0 身份验证显示 500 Internal Server Error, Spring Boot 微服务

在 Spring Security 5 OAuth Client 和 Spring Boot 2.0 中,authorizationGrantType 不能为空