Protocolo Oauth2.0 en la arquitectura de Internet

//  今天主要讲这么几个问题
1.如何保证api接口合理安全调用
2.oauth2.0授权认证平台设计原理
3.oauth2.0认证协议的四种模式
4.oauth2.0实现对api接口保护
https://www.cnblogs.com/blowing00/p/4521135.html
看大佬的讲解吧
我的api 如果让很多合作伙伴访问 请问怎么做
合作伙伴可能会调用到我的接口,此时怎么保证我的开放接口的安全性
我吧我的api 提供给合作伙伴公司,我该如何管理我这个开放接口

这些合作伙伴想要调用我接口,必须要求 申请一个appKey和这个secret  用appkey和密码换取access_token,有了这个access_token 才可以访问我接口
 
 oauth2.0授权协议
  // oauth2.0 有哪几种
  授权码>  获取access_token通过access_token你才能调用我接口
  密码>  你在调用我接口的时候传userName和password 
  简化模式
  客户端模式
  调用接口传递令牌(access_token) 为什么比较安全
  因为令牌是临时且唯一的,有时间限制的
   假设现在我们公司接口需要被很多合作伙伴调用的情况西
   首先我先搭建一个 认证管理web 平台
	就是说你要在我平台申请一个appid和appkey
	
  oauth2.0协议授权模式
  1.合作伙伴首先先要申请appid和appkey  区分不同的合作伙伴[appid 是终身不会发生变化,appkey是可以修改的]
 2.合作伙伴用这个appid和appkey申请一个授权code (认证授权获取授权码code),
 3.拿到code获取 accesstoken,再然后拿到这个access_token 才可以掉我接口 

Inserte la descripción de la imagen aquí


Echemos un vistazo al inicio de sesión del código de escaneo de WeChat de Zhihu
Inserte la descripción de la imagen aquí

https://open.weixin.qq.com/connect/qrconnect?
appid=wx268fcfe924dcb171
&redirect_uri=https%3A%2F%2Fwww.zhihu.com%2Foauth%2Fcallback%2Fwechat%3Faction%3Dlogin%26from%3D
&response_type=code
&scope=snsapi_login
&state=59346f327367534969737557456a5a556e315555325235576e425a5a384f4430#wechat
首先第一步 他会生成一个授权连接,获取授权码code
// 我们可以对比看看微信得官网
https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html

Inserte la descripción de la imagen aquí

嗯,是不是一样的,当我们点击同意的时候,回生成一个code 来回调我们的redirect_uri  
只不过这里页面跳转的太快 我就不演示了
第二步, 后台回用这个code 来生成一个access_token,  意思是我只要拿到这个accessToken就可以调用接口
第三步:根据这个accessToken	此时就可以调用微信接口了,可以获取用户的openId[此时这个openID是腾讯对qq账户设置一个开放的userId,而不是真实的userId]
第四步  根据用户的openId获取用户的信息
accesstoken 有效期 2小时 如果这个accesstoken 过期可以去使用refresh_token去获取最新的access_token
oauth2.0协议角色划分 

Inserte la descripción de la imagen aquí

我们再来看这张图  oauth2.0角色的划分无非就是2个角色
 一个AuthenticationService【认证授权中心】 认证授权,根据appkey 获取授权码,accesstoken 
 一个ResourceService【资源管理器】 被开放的接口检查
 

然后我们先通过Springsecurity搭建一个AuthenticationService
package com.lvhao.auth.service.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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
// 配置登录账号密码
@Component
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    
    
    @Bean
    public PasswordEncoder passwordEncoder() {
    
    
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        http.authorizeRequests()
                .anyRequest().authenticated() // 所有请求都要通过认证
                .and()
                .httpBasic()
                .and()
                .csrf().disable();// 关闭跨域保护

    }

    // 配置登录账号密码
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    
    
        auth.inMemoryAuthentication()
                .withUser("mayiketi")
                .password(passwordEncoder().encode("123456"))
                .authorities("/*");
    }
}

package com.lvhao.auth.service.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
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.AuthorizationServerSecurityConfigurer;
import org.springframework.stereotype.Component;
//
@Component
@EnableAuthorizationServer// 当前项目是一个认证授权中心  开启认证授权
public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
    
    
    @Autowired
    PasswordEncoder passwordEncoder;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    
    
// 检查accesstoken权限
        //允许表单提交,检查accesstoken是否有效的情况下  必须加配置 权限放开
         security.allowFormAuthenticationForClients()
                .checkTokenAccess("permitAll()");
    }

    /*
     * 分配我的appid和appkey
     * */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    
    
        clients.inMemory()
                /*appid*/
                .withClient("mayikt_appid")
                /*密钥*/
                .secret(passwordEncoder.encode( "mayikt_pwd"))
                .authorizedGrantTypes("authorization_code")
                /*所有的接口都可以方位*/
                /*member-service表示只能访问到我的member服务接口不能访问别的接口*/
                //分配appid调用接口的权限
                .scopes("all")
                 .resourceIds("mayikt_resource")
                //  用户选择授权之后跳转到该地址传递code授权码
                .redirectUris("https://www.baidu.com/");
    }
}

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

我此时的回调地址配置的百度  当点击授权的时候 此时会跳到回调地址上返回一个code 

Inserte la descripción de la imagen aquí

  然后第二步就是  用这个code 来换取access_token
  http://localhost:9000/oauth/token?code=2rX4gF&grant_type=authorization_code
  &redirect_uri=https://www.baidu.com/
  &scope=all
  &client_id=mayikt_appid
  &client_secret=mayikt_pwd

Inserte la descripción de la imagen aquí

  看到了吧 根据此时这code 就可以拿到access_token

Inserte la descripción de la imagen aquí

我们下一步可以检查这个token 是否有效  
http://localhost:9000/oauth/check_token?token=787cb830-71b6-4c4d-a7a8-861145efb075

------------------------------------------------?

嗯 我们的认证管理器就搭建完毕了, 然后我们现在搭建我们的资源管理器


@Configuration
@EnableResourceServer
public class ResourceConfig extends ResourceServerConfigurerAdapter {
    
    
    @Value("mayikt_appid")

    private String mayiktAppid;
    @Value("mayikt_pwd")
    private String mayiktAppSecret;

    @Bean
    public PasswordEncoder passwordEncoder() {
    
    
        return new BCryptPasswordEncoder();
    }
    //  去拦截请求判断有没有去传递accesstoken 同时检查accesstoken 是否有效
    @Primary
    @Bean
    public RemoteTokenServices remoteTokenServices() {
    
    

        final RemoteTokenServices tokenServices = new RemoteTokenServices();
        //设置授权服务器cache_token 的完整地址       http://localhost:9000/oauth/check_token
        tokenServices.setCheckTokenEndpointUrl("http://localhost:9000/oauth/check_token");
        //APPID
        tokenServices.setClientId(mayiktAppid);
        //KEY
        tokenServices.setClientSecret(mayiktAppSecret);
        return tokenServices;
     }

    @Override
    public void configure(HttpSecurity http) throws Exception {
    
    
        //设置创建session策略
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
       http.authorizeRequests().anyRequest().authenticated();

    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    
    
        resources.resourceId("mayikt_resource").stateless(true);
    }
}

每当访问资源管理器的时候, 或者调用api的时候,资源管理器首先第一步操作就是调用这个check 来看此时的access_token 是否有效

Inserte la descripción de la imagen aquí

我有个这么个接口,如果此时不携带access_token 的话就会报错异常 

Inserte la descripción de la imagen aquí

看此时携带这个token 的话就不会有异常了 ,并且可以正常访问了

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

我们也可以用 jwt的形式 通过 Bearer+code 写在头中 
  嗯 最后一个问题 就是互联网架构中我们的接口安全如何去做

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_43689953/article/details/109723203
Recomendado
Clasificación