SpringBoot实现标准的OAuth服务提供商

2022-12-09,,,,

⒈添加pom依赖

         <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<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>
<version>2.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>

⒉配置SpringSecurity

 package cn.coreqi.config;

 import org.springframework.context.annotation.Bean;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; @EnableWebSecurity
public class CoreqiWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/oauth/token").permitAll()
.anyRequest().authenticated() //任何请求都需要身份认证
.and().csrf().disable(); //禁用CSRF
} @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("fanqi").password("admin").roles("admin");
} @Bean
public PasswordEncoder passwordEncoder()
{
return NoOpPasswordEncoder.getInstance();
}
}

⒊配置OAuth

 package cn.coreqi.config;

 import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; @Configuration
@EnableAuthorizationServer //开启认证服务
public class CoreqiAuthorizationServerConfig implements AuthorizationServerConfigurer { @Override
public void configure(AuthorizationServerSecurityConfigurer authorizationServerSecurityConfigurer) throws Exception { } @Override
public void configure(ClientDetailsServiceConfigurer clientDetailsServiceConfigurer) throws Exception {
clientDetailsServiceConfigurer.inMemory()
.withClient("coreqi")
.secret("coreqiSecret")
.redirectUris("https://www.baidu.com")
.scopes("ALL")
.authorities("COREQI_READ")
.authorizedGrantTypes("authorization_code");
} @Override
public void configure(AuthorizationServerEndpointsConfigurer authorizationServerEndpointsConfigurer) throws Exception { }
}

⒋测试【如果颁发给用户的令牌没有过期,那么Spring OAuth不会颁发新的令牌,而是将上次的令牌重新返回,不同的是过期时间减少了】

  1.访问http://localhost:8080/登录

    为什么要登录?因为这个地址是我们提供给第三方应用,由第三方应用来引导用户进行授权的,作为服务提供商,我们需要知道,1.是那个应用在请求授权(通过client_id),2.第三方应用在请求我们哪个用户的授权(通过此时登录的用户名密码判断是我们系统中的哪个用户),3.需要我们给第三方应用该用户的哪些权限(通过scope参数,scope参数是由我们自己定义的)。

  2.访问http://localhost:8080/oauth/authorize?response_type=code&client_id=coreqi&redirect_uri=https://www.baidu.com&scope=ALL进行授权,授予权限

    参数介绍:

      response_type:必填,值必须为code

      client_id:必填,客户端id

      redirect_uri:可选,授权码模式下可用

      scope:必须要有,要么在服务器端配置,要么在请求参数中配置。

      state:推荐

  3.跳转到 redirect_uri 【https://www.baidu.com/?code=5HF6y7】拿到授权码

  4.

    ⅰ授权码模式:

      对http://localhost:8080/oauth/token发送post请求,请求头添加Authorization,username为client_id,password为secret。BODY中添加以下参数:

        grant_type:必填,值为authorization_code

        code:授权码

        redirect_uri:可选,授权码模式下可用

        client_id:必填,客户端id

        scope:和上一步请求传一样的值

    

    ⅱ密码模式:

      密码模式实际上是用户把自己在服务提供商的用户名密码告诉了第三方应用,第三方应用拿着用户名密码来服务提供商这里获得授权。这种情况下服务提供商是没法判断这个用户名密码是不是用户真正给你的(万一是你偷的呢)。

      对http://localhost:8080/oauth/token发送post请求,请求头添加Authorization,username为client_id,password为secret。BODY中添加以下参数:      

        grant_type:必填,值为password

        username:服务提供商系统中的用户

        password:服务提供商系统中用户的密码

        scope:和上一步请求传一样的值

      

        密码模式需要对Security和OAuth做一些配置

      

 package cn.coreqi.config;

 import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
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.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; @EnableWebSecurity
public class CoreqiWebSecurityConfig extends WebSecurityConfigurerAdapter { @Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
} @Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/oauth/token").permitAll()
.anyRequest().authenticated() //任何请求都需要身份认证
.and().csrf().disable(); //禁用CSRF
} @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("fanqi").password("admin").roles("admin");
} @Bean
public PasswordEncoder passwordEncoder()
{
return NoOpPasswordEncoder.getInstance();
}
}
 package cn.coreqi.config;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; @Configuration
@EnableAuthorizationServer //开启认证服务器
public class CoreqiAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager; @Autowired
private AuthenticationConfiguration authenticationConfiguration; /**
* password模式需要提供一个AuthenticationManager到AuthorizationServerEndpointsConfigurer
* @param authorizationServerEndpointsConfigurer
* @throws Exception
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer authorizationServerEndpointsConfigurer) throws Exception {
authorizationServerEndpointsConfigurer.authenticationManager(authenticationConfiguration.getAuthenticationManager());
} @Override
public void configure(ClientDetailsServiceConfigurer clientDetailsServiceConfigurer) throws Exception {
clientDetailsServiceConfigurer.inMemory()
.withClient("coreqi")
.secret("coreqiSecret")
.redirectUris("https://www.baidu.com")
.scopes("ALL")
.authorities("COREQI_READ")
.authorizedGrantTypes("authorization_code","password");
} }

    ⅲ刷新令牌

  

SpringBoot实现标准的OAuth服务提供商的相关教程结束。

《SpringBoot实现标准的OAuth服务提供商.doc》

下载本文的Word格式文档,以方便收藏与打印。