spring cloud oauth2的使用

1、创建一个父项目

在这里插入图片描述
依赖不选
在这里插入图片描述
创建好后会只有有一个pom.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.butcher</groupId>
    <artifactId>springcloudoauth2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springcloudoauth2</name>
    <description>springcloudoauth2 project</description>

    <properties>
        <java.version>11</java.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

我们需要修改一下版本号,因为我是以我当前的项目作为背景的,我的项目使用了alibaba的2.2.6版本。
在这里插入图片描述所以将pom修改为:

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/>
    </parent>
    
    <groupId>cn.butcher</groupId>
    <artifactId>springcloudoauth2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springcloudoauth2</name>
    <description>springcloudoauth2 project</description>

    <!-- 打包方式为pom-->
    <packaging>pom</packaging>

    <properties>
        <java.version>11</java.version>
        <spring.boot>2.3.2.RELEASE</spring.boot>
        <spring.cloud>Hoxton.SR9</spring.cloud>
    </properties>

    <dependencies>

        <!-- 因为基本上后面子模块都需要用到web,所以直接在父里面引-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 单元测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>

        <dependencies>
            
           <!--管理springcloud依赖,后续子模块就不用写版本号了-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>

</project>

2、使用maven创建认证服务器

在这里插入图片描述创建一个认证服务器authentication-service
创建包和主启动类

package cn.butcher;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author 谭熙
 * @version 1.0
 * @date 2021/10/30 9:51
 * @description
 */
@SpringBootApplication
public class AuthenticationApplication {
    public static void main(String[] args) {
        SpringApplication.run(AuthenticationApplication.class,args);
    }
}

在这里插入图片描述
创建配置文件application.yml配置端口

server:
  port: 8001

在这个认证模块的pom.xml中加入oauth2的依赖

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>springcloudoauth2</artifactId>
        <groupId>cn.butcher</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>authentication-service</artifactId>

    <dependencies>
    	
    	<!--oauth2依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
    </dependencies>

</project>

PS:如果maven爆红了,刷新也没用,请清楚idea缓存并重启idea尝试

3、编写认证配置

接下来就是编写认证有关的了,因为这是由spring实现的一套oauth2,是基于spring security的
在这里插入图片描述按住ctrl+鼠标左键点进去,其实会发现这里有很多自动配置,管理了很多依赖

第一层,发现是security和oauth2的整合
在这里插入图片描述点击security进入第二层
在这里插入图片描述
再继续点
在这里插入图片描述

到这思考,可不可以直接使用spring security实现的oauth2捏,后面我们在尝试,这里稍微埋点坑。

创建auth包,这个包下全部是关于认证配置的
所以根据spring security的习惯,我们需要先编写一个自己UserDetails,将来的用户信息全部封装到这里面。

package cn.butcher.auth;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author 谭熙
 * @version 1.0
 * @date 2021/10/30 10:30
 * @description
 */
public class MyUserDetail implements UserDetails {

    private String username;
    private String password;
    private String perms;

    public MyUserDetail() {
    }

    public MyUserDetail(String username, String password, String perms) {
        this.username = username;
        this.password = password;
        this.perms = perms;
    }

    // 获取权限集合,这里我们自己定义权限编写的规则,通过逗号分隔权限
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return Stream.of(perms.split(","))
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());
    }

    // 获取密码,返回当前密码
    @Override
    public String getPassword() {
        return this.password;
    }

    // 获取用户名,返回当前用户名
    @Override
    public String getUsername() {
        return this.username;
    }

    // 账户是否没过期
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    // 账户是否未锁定
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    // 凭证是否没过期
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    // 是否启用此用户
    @Override
    public boolean isEnabled() {
        return true;
    }
}

配置security,配置密码加密器,后面会用到。放行登录,如果登录都不放行,那怎么认证?

package cn.butcher.auth;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author 谭熙
 * @version 1.0
 * @date 2021/10/30 10:45
 * @description
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // 密码加密,security所有的密码都需要经过此加密器加密才能使用
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    // 认证管理器
    @Bean
    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    // http请求相关配置
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 关闭csrf
        http.csrf().disable()

                // 认证所有请求,将所有请求放行,因为我们使用oauth2进行认证的
                .authorizeRequests()
                .anyRequest().permitAll()

                // 允许表单登录便于用户填写认证信息
                .and()
                .formLogin()

                // 允许登出
                .and()
                .logout();
    }
}

配置用户认证服务,在security接收到用户的登录信息时,会自动调用这里的方法进行验证,这个验证的逻辑需要我们自己实现。

package cn.butcher.auth;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

/**
 * @author 谭熙
 * @version 1.0
 * @date 2021/10/30 10:53
 * @description
 */
@Service
public class MyUserDetailService implements UserDetailsService {

    // 这是在SecurityConfig中配置的密码加密,这里自动导入
    @Autowired
    private PasswordEncoder passwordEncoder;

    // security在获取到用户名后会自动调用这个方法进行认证,我们只需要实现逻辑
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        // 如果登录的用户是butcher 或者 tanxi ,
        // 就说明用户存在,并返回此用户详细信息,否则返回null
        // 这里的用户信息还可以更多
        if (username.equals("butcher") || username.equals("tanxi")){
            return new MyUserDetail(
                    username,
                    passwordEncoder.encode(username),
                    "sys:read,sys:write");
        }
        return null;

    }
}

总要有个地方存放token,所以需要配置token存储的位置,这里可以选择将token放在内存、数据库、redis等地方。。

package cn.butcher.auth;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

/**
 * @author 谭熙
 * @version 1.0
 * @date 2021/10/30 11:04
 * @description
 */
@Configuration
public class TokenConfig {

    @Bean
    public TokenStore tokenStore(){
        // 这里还可以配置很多token存储的地方
        // JdbcTokenStore、JwtTokenStore、RedisTokenStore...
        // 我这里就直接放在内存中了,不过需要注意的是,当上线用户量激增的时候,放在内存中可能会出大事情
        return new InMemoryTokenStore();
    }
}

既然用到了oauth2,那肯定要进行oauth2的配置,比如设置token的存活时间,刷新token的存活时间等

package cn.butcher.auth;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
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;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;

/**
 * @author 谭熙
 * @version 1.0
 * @date 2021/10/30 11:09
 * @description
 */
@Configuration
@EnableAuthorizationServer
public class Oauth2Config extends AuthorizationServerConfigurerAdapter {

    @Autowired
    PasswordEncoder passwordEncoder;

    // 配置客户端认证
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

        // 去内存里找已认证的客户端
        clients.inMemory()

                // 客户端id ==> AppID
                .withClient("bt-client-1")

                // 客户端密码 ==> AppSecret
                .secret(passwordEncoder.encode("bt123"))

                // 允许这个客户端访问的资源为sale-resources,这个等配置资源服务器的时候会用到
                .resourceIds("sale-resources")

                // 授权类型,四大种嘛 依次为授权码、密码、客户端、简单。
                // 最后那个是刷新token,在token即将过期的时候刷新token拿到新的token
                .authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")

                // 作用域范围,这也是我们自定的,将我们的应用划分作用域范围,确保这个客户端只能请求固定范围内的资源
                .scopes("sale")

                // 是否自动统一授权,设置为false,就是需要用户点击同意或者不同意
                .autoApprove(true)

                // 用户同意后跳转的地址是,这个地址后面会携带一个code,这个code,用来换取token
                .redirectUris("http://www.baidu.com");

        // 还可以继续and()配置其他客户端
    }

    @Autowired
    TokenStore tokenStore;

    @Autowired
    private ClientDetailsService clientDetailsService;



    // 配置token认证服务
    @Bean
    public AuthorizationServerTokenServices tokenServices(){

        // DefaultTokenServices是AuthorizationServerTokenServices的一个默认实现类
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();

        // 设置客户端认证服务,就和我们前面写的MyUserDetailService的作用差不多
        // 帮我们拿得到的客户端id去验证密码
        // 这个认证服务有两个实现类,一个是基于内存的,一个是基于jdbc的
        // 当我们需要去数据库中拿到客户端密码比较,就可以用jdbc的
        defaultTokenServices.setClientDetailsService(clientDetailsService);

        // 是否支持刷新token
        defaultTokenServices.setSupportRefreshToken(true);

        // 设置token要存储的位置
        defaultTokenServices.setTokenStore(tokenStore);

        // 设置token的有效存活时间
        defaultTokenServices.setAccessTokenValiditySeconds(300);

        // 设置刷新token的有效存活时间
        defaultTokenServices.setRefreshTokenValiditySeconds(1500);

        return defaultTokenServices;
    }

    // 在security中配置的认证管理器
    @Autowired
    AuthenticationManager authenticationManager;

    // 将认证管理器、认证码服务、token服务组合
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints){
        // 认证管理器
        endpoints.authenticationManager(authenticationManager)
                // 认证码服务
                .authorizationCodeServices(new InMemoryAuthorizationCodeServices())
                // token服务
                .tokenServices(tokenServices())
                // 允许请求token的方式
                .allowedTokenEndpointRequestMethods(HttpMethod.POST);
    }

    // 放行与认证有关的接口,如果认证的接口都不放,那么何谈认证
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.tokenKeyAccess("permitAll()")
                .checkTokenAccess("permitAll()")

                // 允许表单认证客户端
                .allowFormAuthenticationForClients();
    }
}

如果都按照上面配置了,那么就可以进行测试了,一般都是用postman测嘛,我们先不管拿到token后如何获取其他服务的资源,我们先要拿到token,检查token是否有效,刷新token,这里没问题了,咱们再继续

4、测试

启动认证服务

PS: 如果启动爆红
在这里插入图片描述
有可能是java版本太高了,我用的11,用8就不会报。
在加一个vm参数:–add-opens java.base/java.lang=ALL-UNNAMED
再启动就可以了

1、授权码模式
打卡浏览器请求:http://localhost:8001/oauth/authorize?client_id=bt-client-1&response_type=code&scope=sale&redirect_uri=http://www.baidu.com
注意这里有四个参数:

  • client_id ==》 客户端id,就是在Oauth2Config那你配置的客户端id
  • response_type==》响应类型,我们期望能给咱返回一个授权码,用于请求真正的token
  • scope ==》 作用域,同样是Oauth2Config里定好的,验证客户端想要请求的作用域我们有没有给它设置
  • redirect_uri ==》 重定向的地址,注意这里也是你在Oauth2Config写好的,这个不匹配也不行,重定向后会携带一个参数code就是授权码

在这里插入图片描述
第一次会要求登录,用户名密码就是你在MyUserDetailService那里配置的。
登录成功后:
在这里插入图片描述
拿到授权码,打开postman
发送post请求:http://localhost:8001/oauth/token

携带以下5个参数

  • client_id
  • client_secret 这里是Oauth2Config那里配置的这个客户端的密匙
  • grant_type
  • code 将授权码加在此处
  • redirect_uri

响应结果
在这里插入图片描述

{
    "access_token": "bc492e36-eb02-4bc2-9619-e66041da6acd",
    "token_type": "bearer",
    "refresh_token": "8a38b119-a0d1-4cdb-a844-797ecd5e0af9",
    "expires_in": 299,
    "scope": "sale"
}
  • access_token 认证的token,请求资源的时候将这个带上即可
  • token_type token的类型
  • refresh_token 可以通过它刷新token,拿到新的token,原来的会失效
  • expires_in 在几秒后过期
  • scope 作用域

既然可以获取token那么我们测试一下这个token是否可用。
使用postman请求:http://localhost:8001/oauth/check_token,带上参数token以及它的值
在这里插入图片描述

在我打字的这段时间,上次请求的token已经过期了,我们刷新一下token
使用postman请求:http://localhost:8001/oauth/token并带上四个参数

  • client_id
  • client_secret
  • grant_type 注意这里的类型是refresh_token
  • refresh_token

在这里插入图片描述拿到了新的token,再去检查token
在这里插入图片描述
token在有效期内,咱么成功拿到了用户信息

{
    "aud": [
        "sale-resources"
    ],
    "user_name": "butcher",
    "scope": [
        "sale"
    ],
    "active": true,
    "exp": 1635575837,
    "authorities": [
        "sys:read",
        "sys:write"
    ],
    "client_id": "bt-client-1"
}

2、密码模式
这种就简单一些了,不需要授权码,将用户密码一起放在参数里发出去
请求地址:http://localhost:8001/oauth/token
参数:

  • client_id
  • client_secret
  • grant_type == 》注意这里是password
  • username
  • password

在这里插入图片描述
3、客户端模式
这个更简单了,用户名密码都不用填
请求地址:http://localhost:8001/oauth/token
参数:

  • client_id
  • client_secret
  • grant_type == 》注意这里是client_credentials
    在这里插入图片描述
    4、简单模式
    这个直接在浏览器发请求就能得到:http://localhost:8001/oauth/authorize?client_id=bt-client-1&response_type=token&scope=sale&redirect_uri=http://www.baidu.com
    请求地址:http://localhost:8001/oauth/authorize
    参数:
  • client_id
  • response_type ==》返回类型写token
  • scope
  • redirect_uri
    在这里插入图片描述
    在这里插入图片描述

5、编写一个资源

创建一个新的子模块sale-service作为我们众多服务中的一个服务,依然使用maven创建即可。

创建配置文件,修改端口

server:
  port: 8002

创建包和启动类

package cn.butcher;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author 谭熙
 * @version 1.0
 * @date 2021/10/30 14:50
 * @description
 */
@SpringBootApplication
public class SaleApplication {
    public static void main(String[] args) {
        SpringApplication.run(SaleApplication.class,args);
    }
}

创建一个controller

package cn.butcher.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 谭熙
 * @version 1.0
 * @date 2021/10/30 14:52
 * @description
 */
@RestController
public class SaleController {

    @GetMapping("/order")
    public Map<String,Object> getOrder(){
        Map<String,Object> data = new HashMap<>();
        data.put("status",200);
        data.put("msg","获取订单信息成功");
        data.put("data",new String[]{"我是订单信息1","我是订单信息2"});
        return  data;
    }
}

启动服务,尝试请求/order接口
在这里插入图片描述
请求成功,接下来将它配置为资源
引入oauth2依赖

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>springcloudoauth2</artifactId>
        <groupId>cn.butcher</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>sale-service</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
    </dependencies>
</project>

编写配置,创建auth包

首先是security的配置

package cn.butcher.auth;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * @author 谭熙
 * @version 1.0
 * @date 2021/10/30 15:01
 * @description 主要是放行所有请求,因为我们是需要oauth2来认证了
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .anyRequest()
                .permitAll();
    }
}

配置为资源服务器

package cn.butcher.auth;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;

/**
 * @author 谭熙
 * @version 1.0
 * @date 2021/10/30 15:03
 * @description
 */
@Configuration
@EnableResourceServer
public class Oauth2Config extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        
        // 请求认证服务器认证,但这么做并不好,请求多了以后,认证服务器压力山大
        RemoteTokenServices tokenServices = new RemoteTokenServices();
        
        // 设置请求的地址
        tokenServices.setCheckTokenEndpointUrl("http://localhost:8001/oauth/check_token");
        
        // 设置客户端id
        tokenServices.setClientId("bt-client-1");
        
        // 设置客户端密码
        tokenServices.setClientSecret("bt123");
        
        // 设置资源名字,注意这个资源名字和认证服务器中的Oauth2Config那配置的资源名称是对应的
        resources
                .resourceId("sale-resources")
                .tokenServices(tokenServices);
    }
    
    @Override
    public void configure(HttpSecurity http) throws Exception {
        
        // 检查是否有正确的作用域
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/**")
                .access("#oauth2.hasScope('sale')");
    }
}

OK,我们再次请求这个/order接口
在这里插入图片描述
这时就提示未授权了,因为我们没有token
我们需要在请求头中加入token信息
注意格式为:Authorization=token类型+空格+token

在这里插入图片描述

6、小结

这只是一个简单的演示,真正使用我们应该是在数据库获取redis中存储token信息,并且资源服务器去确认token的时候应该不用每次都去认证服务器请求才是,所以还在继续改进中。

找个时间填一下上面提到的一个坑,就是
在这里插入图片描述也就是说,这种用法要过期了,在下一版本中会将security从springcloud中移除。

所以其实我们可以研究一下,springcloud oauth2到底用了security的什么依赖?
经过我的测试,其实只用到了一个,那就是oauth2的自动配置

 <dependency>
     <groupId>org.springframework.security.oauth.boot</groupId>
     <artifactId>spring-security-oauth2-autoconfigure</artifactId>
     <version>2.1.2.RELEASE</version>
 </dependency>

也就是说其实我们并不需要springcloud的依赖,那么,我们的pom.xml可以变为
父pom

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/>
    </parent>

    <modules>
        <module>authentication-service</module>
        <module>sale-service</module>
    </modules>

    <groupId>cn.butcher</groupId>
    <artifactId>springcloudoauth2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springcloudoauth2</name>
    <description>springcloudoauth2 project</description>

    <!-- 打包方式为pom-->
    <packaging>pom</packaging>

    <properties>
        <java.version>11</java.version>
        <spring.boot>2.3.2.RELEASE</spring.boot>
        <spring.oauth2>2.1.2.RELEASE</spring.oauth2>
    </properties>

    <dependencies>

        <!-- 因为基本上后面子模块都需要用到web,所以直接在父里面引-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 单元测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
        </dependency>

        <!--oauth2依赖-->
        <dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
            <version>${spring.oauth2}</version>
        </dependency>
    </dependencies>

</project>

子模块完全不用引

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>springcloudoauth2</artifactId>
        <groupId>cn.butcher</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>authentication-service</artifactId>
    
</project>
<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>springcloudoauth2</artifactId>
        <groupId>cn.butcher</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>sale-service</artifactId>

</project>

经测试,代码不变,运行正常。

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: SpringCloud Oauth2 是一种基于OAuth2的开放授权框架,可以帮助开发者快速构建安全的RESTful API。 springcloud oauth2 是一种开放授权标准,它可以帮助开发人员更容易地为应用程序实现安全的身份验证和授权。好的,下面是关于 Spring CloudOAuth2 的一些解释和概述。 Spring Cloud 是一个基于 Spring 框架的开发工具集,它可以帮助开发者快速构建分布式系统和微服务架构。Spring Cloud 提供了多种功能模块,包括服务发现、配置管理、负载均衡、断路器等等,以便于开发者构建和管理微服务架构。 OAuth2 是一种授权框架,可以用于保护 API、Web 应用程序或其他服务的访问权限。OAuth2 通过颁发访问令牌(Access Token)来实现授权,访问令牌是在用户授权的情况下,由授权服务器颁发给客户端的。 Spring Cloud 提供了一个名为 Spring Cloud Security 的安全框架,它可以集成 OAuth2,以实现安全访问控制和身份验证。通过 Spring Cloud Security 和 OAuth2 的集成,开发者可以构建安全的微服务架构,以保护系统和数据的安全性。 在 Spring Cloud 中,集成 OAuth2 的方式有很多种,比如使用 Spring Security OAuth2 或者使用 Spring Cloud Security OAuth2,开发者可以根据自己的需求和技术栈选择适合自己的方案。 ### 回答2: Spring Cloud OAuth2 是Spring Cloud 微服务框架中的一种安全认证授权的解决方案。它可以为我们提供 OAuth2 认证和授权服务,帮助我们实现微服务架构中的单点登录、安全控制等功能。 OAuth2 具有很高的灵活性和可定制性,可以实现多种认证方式和授权模式,例如授权码模式、密码模式、客户端模式等。Spring Cloud OAuth2 基于 Spring Security 实现了 OAuth2 协议,并且采用了简化的配置方式和自动化的注册中心,简化了我们的认证授权开发。 在 Spring Cloud OAuth2 中,应用程序被分为两类:认证服务器和资源服务器。认证服务器主要负责处理登录请求和颁发访问令牌,而资源服务器则根据令牌来检查并限制对受保护资源的访问。 除此之外,Spring Cloud OAuth2 还提供了一些附加功能,如 Spring Cloud Security,它是 Spring Security 的增强版,提供许多安全功能和 OAuth2 支持,可以帮助我们轻松地实现授权码、密码和客户端等多种认证模式。 总之,Spring Cloud OAuth2 可以作为我们微服务架构中的认证和授权解决方案,帮助我们实现单点登录、安全控制等功能。通过该解决方案,我们可以为不同的服务提供不同的授权策略和安全机制,提高微服务架构的稳定性和安全性。 ### 回答3: SpringCloud OAuth2是基于Spring CloudSpring Security实现的一种开源的身份验证和授权协议。它主要用于实现用户认证和授权功能,并提供了一些常见的认证协议和授权机制,例如OAuth2、OpenID Connect、JWT等。通过使用SpringCloud OAuth2,开发人员可以以一种简单、可扩展的方式为应用程序添加安全性,同时也可以更好地控制资源的访问。 SpringCloud OAuth2的核心是通信协议和两种角色(客户端和资源服务器)。其中,客户端是指请求API资源的应用程序,而资源服务器则负责保护和提供这些API资源。为了实现安全机制,SpringCloud OAuth2引入了许多重要的概念: 1、认证服务器:用于验证用户身份的服务器,通知客户端提供的令牌是否有效。 2、客户端:请求受保护的资源的应用程序。 3、资源服务器:保护和提供受保护资源的服务器。 4、访问令牌:许可授予客户端访问资源的票据。 5、刷新令牌:用于刷新和获取新的访问令牌的令牌。 6、授权代码:通过重定向浏览器并向客户端授权服务器发送欲请求访问的资源,以获取访问和刷新令牌。 7、JWT:JSON Web Tokens,一种安全地传输信息并可验证的JSON标准。 总之,SpringCloud OAuth2是一项非常有用的技术,可帮助开发人员实现应用程序的身份验证和授权。它提供了一些常见的认证协议和授权机制,例如OAuth2、OpenID Connect、JWT等,可以让开发人员更好地控制资源的访问。同时它还使用了一系列的重要概念和角色,如认证服务器、客户端、资源服务器、访问令牌、刷新令牌、授权代码、JWT等,为应用程序添加安全性和可扩展性提供了有力的保障。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值