使用Spring boot 快速 搭建 OAuth2 Server

来源:互联网 发布:js点击弹窗代码 编辑:程序博客网 时间:2024/06/03 17:41

目前国内很多平台(QQ,微信,微博等)都提供了OAuth2服务,本文不是针对OAuth2协议的教程,故阅读本文之前,如果对OAuth2协议还不熟悉的同学可查询相关资料,本文旨在以最简单的方式,使用Spring OAuth2 框架,快速搭建OAuth2服务。

前提

阅读本文之前,你需要了解:

  • Spring Boot
  • Spring MVC
  • Spring Security
  • Google 浏览器插件Postman

Maven依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0</modelVersion>  <artifactId>oauth2</artifactId>  <packaging>jar</packaging>  <name>oauth2</name>  <url>http://maven.apache.org</url>  <parent>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-parent</artifactId>    <version>1.5.6.RELEASE</version>  </parent>  <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <java.version>1.8</java.version>  </properties>  <dependencies>    <dependency>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-starter-web</artifactId>    </dependency>    <dependency>      <groupId>org.springframework.security.oauth</groupId>      <artifactId>spring-security-oauth2</artifactId>    </dependency>  </dependencies></project>

本项目需要添加的依赖非常简单,一共只有两个,一个是Spring Web,另一个是Spring OAuth2。

接下来是本文的核心,一共三个配置类。

SecurityConfig

@Configuration@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter {    @Override    protected void configure(AuthenticationManagerBuilder auth) throws Exception {        auth.inMemoryAuthentication()            .withUser("user").password("123456").authorities("ROLE_USER");    }    @Override    protected void configure(HttpSecurity http) throws Exception {        http.httpBasic()            .and().csrf().disable()            .authorizeRequests()            .antMatchers("/login").permitAll()            .anyRequest().authenticated()            .and()            .formLogin()            .and()            .logout().permitAll();    }    @Override    @Bean    public AuthenticationManager authenticationManagerBean() throws Exception {        return super.authenticationManagerBean();    }}

此处主要做了两件事情:

  • 配置系统用户,这里使用内存存储,添加了用户名为 user ,角色为 USER 的用户
@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {    auth.inMemoryAuthentication()        .withUser("user").password("123456").authorities("ROLE_USER");}
  • 配置了默认表单登陆以及禁用了 csrf 功能,并开启了httpBasic 认证
    @Override    protected void configure(HttpSecurity http) throws Exception {        http.httpBasic()            .and().csrf().disable()            .authorizeRequests()            .antMatchers("/login").permitAll()            .anyRequest().authenticated()            .and()            .formLogin()            .and()            .logout().permitAll();    }

AuthorizationServerConfig

@Configuration@EnableAuthorizationServerpublic class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {    @Autowired    @Qualifier("authenticationManagerBean")    private AuthenticationManager authenticationManager;    @Override    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {        clients.inMemory()            .withClient("client").secret("123456").scopes("read")            .authorizedGrantTypes("authorization_code")            .redirectUris("https://www.getpostman.com/oauth2/callback");    }    @Override    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {        endpoints.authenticationManager(authenticationManager);    }}

这个类是OAuth2认证的核心配置类,在这个类中,配置了OAuth Client的信息,这里有几个地方需要注意:

  • @EnableAuthorizationServer 这个注解告诉 Spring 这个应用是 OAuth2 的授权服务器

  • 必须配置 authorizedGrantTypes ,它代表了OAuth Client允许认证的类型,其值主要有:

    • authorization_code
    • password
    • client_credentials
    • implicit
    • refresh_token

    这个配置项接受的类型是个数组,允许配置多个;关于这几种类型的区别,请查看 http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html ,这里不再赘述

  • redirectUris 关于这个配置项,是在 OAuth2协议中,认证成功后的回调地址,因为稍后我们会使用 Postman 作为测试工具,故此处值固定为 https://www.getpostman.com/oauth2/callback ,此值同样可以配置多个

ResourceServerConfig

@Configuration@EnableResourceServerpublic class ResourceServerConfig extends ResourceServerConfigurerAdapter {    @Override    public void configure(ResourceServerSecurityConfigurer resources) {        resources.resourceId("users-info");    }    @Override    public void configure(HttpSecurity http) throws Exception {        http            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)            .and()            .requestMatchers()            .antMatchers("/users/**")            .and().authorizeRequests()            .antMatchers("/users/**")            .authenticated();    }}

这个类表明了此应用是OAuth2 的资源服务器,此处主要指定了受资源服务器保护的资源链接,我们将提供以下的资源:

@RestController@RequestMapping("users")public class UserController {    @GetMapping("me")    public Principal me(Principal principal) {        return principal;    }}

注:

资源服务器可以和授权服务器是同一个,也可以分开部署

最后,我们还需添加 application.yml , 配置资源服务器的filter的顺序

server:  port: 8043  context-path: /uaalogging:  level:    org.springframework.security: DEBUGspring:  application:    name: oauth-serversecurity:  oauth2:    resource:      serviceId: ${PREFIX:}resource      # refer to: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.5-Release-Notes#oauth-2-resource-filter      filter-order: 3

此处的 filter-order 非常重要,因为自Spring Boot 1.5.* 之后,resource server 的 filter 的顺序默认在 basic authentication filter chain 之后,所以如果不配置此项,将会导致使用 access_token 访问 resource server 的时候返回 401 状态码。

好了,所有的开发工作已经完成,无需任何其他配置,现在我们启动服务器,并通过 Postman 访问 http://localhost:8043/uaa/users/me

这里写图片描述

因为现在还没通过认证,所以服务器将返回401 的状态码,并返回以上的错误信息。

现在我们使用 Postman 来获取access_token ,首先选择 Authorization Tab, 然后选择 TypeOAuth2.0 ,最后点击 Get New Access Token 按钮:

这里写图片描述

此时将弹出以下界面:
这里写图片描述

我们填入对应的信息:

  • Token Name: access_token
  • Auth URL: http://localhost:8043/uaa/oauth/authorize
  • Access Token URL: http://localhost:8043/uaa/oauth/token
  • Client ID: client
  • Client Secret: 123456
  • Grant Type: Authorization Code

此处配置的client相关信息对应了我们在 AuthorizationServerConfig 里面的配置,之前配置的回调地址也来自于此处的 Callback URL

接下来点击Request Token 按钮,在弹出的登陆界面中输入我们之前在 SecurityConfig 中配置的用户信息,选择Approval 并点击 Authorize 按钮,即可获取 access_token :

这里写图片描述

这里写图片描述

这里写图片描述

到这里我们就成功的获取了 token,此时再次调用 users/me Api,如无意外,将会得到以下的结果:

这里写图片描述

好了,本次关于搭建Spring OAuth服务的教程到此结束,相关源码请访问: OAuth2 Server Demo

另外,关于Spring OAuth服务更高级的用法,请访问我的另一个项目: MCloud-OAuth-Server

这个项目实现了以下的功能:

  • 使用 JWT Token进行认证
  • 多Resource Sever
  • 使用数据库存储用户以及OAuth Client信息
  • 提供相关的Rest API进行用户及 Client的管理
  • 结合了Spring Cloud