Spring Cloud oAuth2(一)搭建授权服务器以及访问

前言

这里在对springcloud ouath2学习的过程中遇到的问题和解决办法做一个简单的总结。

开始

用Spring Cloud oAuth2的前提是必须对Spring Security有所了解,两者是相辅相成的,首先让我们对Spring Cloud oAuth2有个大概的了解:

  • Spring Cloud oAuth2 主要应用于认证与授权,场景多是在不提供密码的前提下授权第三方应用访问用户的资源。( 参考:什么是oAth2)

  • Spring Cloud oAuth2主要有三大块:资源所有者、授权服务提供者、客户端 。( 参考:oAuth2交互流程)

授权

Spring Cloud版本Greenwich.SR2,Spring Boot版本2.1.10.RELEASE,相关pom以及配置省略。
这里只简单实现授权服务器,首先实现Spring Security权限管控三个重要的方法:

@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailService userDetailService;

    //配置哪些需要验证
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //1.配置所有请求都需要经过验证
        http.authorizeRequests().anyRequest().authenticated().and().csrf().disable().formLogin().permitAll();
    }

	//版本需要配置密码加密方式
    @Bean
    public PasswordEncoder passwordEncoder()
    {
        return  new BCryptPasswordEncoder();
    }


    //配置验证的方式和加密方式
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder());
    }

    //配置验证管理器
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

重写UserDetailsService :

//实现用户查询权限
@Service
public class UserDetailService implements UserDetailsService {

    @Autowired
    private UserDao userDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    //这里的dao层是直接实现jpa
        return userDao.findByUsername(username) ;
    }
}

简单的spring security实现就完成了,下面实现AuthorizationServerConfigurerAdapter授权逻辑:

@Configuration
@EnableAuthorizationServer
public class AutherizationServerConfig extends AuthorizationServerConfigurerAdapter {

	//注入密码验证方式,下面客户端密码也需要同样的方式
    @Autowired
    private PasswordEncoder passwordEncoder;
	
	//token放在数据库中
    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

	//添加授权,启用密码授权的方式
    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

	//获取数据库中的权限等
    @Autowired
    private UserDetailService userDetailService;

    //授权服务token安全配置
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security
        		//不拦截所有获取token的访问
                .tokenKeyAccess("permitAll()")
                //验证token
                .checkTokenAccess("isAuthenticated()")
                .allowFormAuthenticationForClients();
    }

    //客户端配置
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients
        		//客户端放在内存中(可放在数据库里面或者非关系型数据库)
                .inMemory()
                //客户端id
                .withClient("smith")
                //密码加密方式(版本必须,不然报错)
                .secret(passwordEncoder.encode("smith12345"))
                //这里有四种授权方式,下面专门细说
                .authorizedGrantTypes("refresh_token","password")
                //域
                .scopes("all");

    }


    //授权节点服务配置
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                //存储在jdbc里面
                .tokenStore(new JdbcTokenStore(dataSource))
                .authenticationManager(authenticationManager)
                .userDetailsService(userDetailService);
    }
}

四种授权方式以及访问方式

四种方式得不同在于客户端配置(ClientDetailsServiceConfigurer)的地方,下面代码只列出对客户端配置的修改。
  • 授权码方式authorization_code

    相关配置:

  		clients
                //客户端放在内存中(可放在数据库里面或者非关系型数据库)
                .inMemory()
                //客户端id
                .withClient("kevin")
                //密码加密方式(版本必须,不然报错)
                .secret(passwordEncoder.encode("kevin12345"))
                //授权码的方式
                .authorizedGrantTypes("authorization_code","refresh_token")
                //返回地址(后面会跟授权码)
                .redirectUris("http://www.baidu.com")
                //域
                .scopes("all");
     如何访问:
  1. 浏览器链接访问http://localhost:9002/auth/oauth/authorize?response_type=code&client_id=kevin&client_secret=kevin12345&redirect_uri=http://www.baidu.com&scope=all
    第一次授权需要登陆验证

    登陆过后点击授权:
    在这里插入图片描述
    授权后获得验证码:
    在这里插入图片描述

 		 clients
                //客户端放在内存中(可放在数据库里面或者非关系型数据库)
                .inMemory()
                //客户端id
                .withClient("kevin")
                //密码加密方式(版本必须,不然报错)
                .secret(passwordEncoder.encode("kevin12345"))
                //这里有四种授权方式,下面专门细说
                .authorizedGrantTypes("password","refresh_token")
                //域
                .scopes("all");
     如何访问:
		clients
                //客户端放在内存中(可放在数据库里面或者非关系型数据库)
                .inMemory()
                //客户端id
                .withClient("kevin")
                //密码加密方式(版本必须,不然报错)
                .secret(passwordEncoder.encode("kevin12345"))
                //这里有四种授权方式,下面专门细说
                .authorizedGrantTypes("implicit","refresh_token")
                .redirectUris("http://www.baidu.com")
                //域
                .scopes("all");
     如何访问:
  1. 浏览器访问http://localhost:9002/auth/oauth/authorize?response_type=token&client_id=kevin&client_secret=kevin12345&redirect_uri=http://www.baidu.com&scope=all
    在这里插入图片描述
  • 客户端方式client_credentials

    相关配置:
  		clients
                //客户端放在内存中(可放在数据库里面或者非关系型数据库)
                .inMemory()
                //客户端id
                .withClient("kevin")
                //密码加密方式(版本必须,不然报错)
                .secret(passwordEncoder.encode("kevin12345"))
                //这里有四种授权方式,下面专门细说
                .authorizedGrantTypes("client_credentials","refresh_token")
                //域
                .scopes("all");
     如何访问:
  1. post请求http://localhost:9002/auth/oauth/token?grant_type=client_credentials&client_id=kevin&client_secret=kevin12345

在这里插入图片描述
四种授权模式得使用场景需要自己去领会,这里使用较少,不做赘述。

发布了7 篇原创文章 · 获赞 1 · 访问量 399

猜你喜欢

转载自blog.csdn.net/qq_35427539/article/details/103541298