OAuth2是目前最流行的授权机制,用来授权第三方应用,获取用户数据。允许用户授权B应用不提供帐号密码的方式去访问该用户在A应用服务器上的某些特定资源。
资源所有者(Resource Owner):拥有受保护资源(如用户资料、照片、视频等)的用户。
客户端(Client):想要访问资源所有者资源的第三方应用程序。
授权服务器(Authorization Server):处理客户端的授权请求并发放访问令牌。
资源服务器(Resource Server):存储受保护的资源,并在访问令牌的授权下提供资源。
访问令牌(Access Token):授权服务器发放的用于访问资源的令牌。
回调URL(Callback URL):客户端在申请授权时提供的 URL,用于在授权成功后将访问令牌发送给客户端。
资源所有者(Resource Owner):这是拥有受保护资源的用户。例如,一个用户可能有存储在云服务提供商的文件。
授权服务器(Authorization Server):这是处理请求和响应的中央服务器。它授权客户端访问资源所有者的资源。
资源服务器(Resource Server):这是存储和提供受保护资源的服务器。例如,云服务提供商可能会有一个资源服务器,它存储用户的文件。
客户端(Client):这是想要访问资源所有者的资源的客户端应用程序。例如,一个云存储同步工具的移动应用程序可能会扮演客户端的角色。
授权码(Authorization Code):
客户端向资源所有者请求授权。
资源所有者同意授权,并返回一个授权码。
客户端使用授权码向授权服务器请求访问令牌。
授权服务器验证授权码,并发放访问令牌。
隐藏式(Implicit):
客户端直接向资源服务器请求受保护的资源,并在 URL 中携带访问令牌。
资源服务器验证访问令牌,并响应请求。
密码式(Password):
客户端使用资源所有者的用户名和密码向授权服务器请求访问令牌。
授权服务器验证用户名和密码,并发放访问令牌。
客户端凭证(Client Credentials):
客户端使用其客户端凭证(如客户端ID和客户端密钥)向授权服务器请求访问令牌。
授权服务器验证客户端凭证,并发放访问令牌。
在实际应用中,根据应用程序的需求和安全性要求,开发人员可以选择适当的授权模式。对于Web应用程序,通常使用授权码或隐藏式;对于移动应用程序,通常使用隐藏式或客户端凭证。密码式通常不推荐使用,因为它可能会导致密码泄露。
用户:就是注册的用户
客户端:就是我们的前端项目
授权服务器:我们可以专门在后台创建一个专门管授权的微服务
资源微服务:像其他的订单微服务,什么搜索微服务拉都可以看做用户能够访问的资源
1. 创建父项目

2. 启动nacos

3. 导入依赖

-
- <dependency>
- <groupId>org.springframework.security.oauthgroupId>
- <artifactId>spring-security-oauth2artifactId>
- <version>2.3.5.RELEASEversion>
- dependency>
-
-
- <dependency>
- <groupId>org.springframework.securitygroupId>
- <artifactId>spring-security-jwtartifactId>
- <version>1.1.0.RELEASEversion>
- dependency>
-
- <dependency>
- <groupId>org.springframework.cloudgroupId>
- <artifactId>spring-cloud-starter-openfeignartifactId>
- dependency>

- @Bean
- public BCryptPasswordEncoder bCryptPasswordEncoder(){
- return new BCryptPasswordEncoder();
- }

- import org.springframework.context.annotation.Configuration;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- 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 javax.annotation.Resource;
-
- @Configuration
- @EnableAuthorizationServer
- public class MyOauthConfig extends AuthorizationServerConfigurerAdapter {
-
- @Resource
- private BCryptPasswordEncoder bCryptPasswordEncoder;
- /*
- * authorization_code 授权码模式
- * password 密码模式
- * client_credentials 客户端模式
- * implicit 简单模式
- */
- @Override
- public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
-
- // 将客户端的信息配置在内存中
- clients.inMemory()
- .withClient("admin")// 客户端id
- .secret(bCryptPasswordEncoder.encode("123456"))// 客户端密码
- .redirectUris("https://www.baidu.com")// 客户端重定向地址
- .scopes("all")// 客户端授权范围
- .authorities("all")// 客户端权限
- .authorizedGrantTypes("authorization_code")// 客户端授权类型
- .autoApprove(true);// 是否自动授权
- }
- }

- import org.springframework.context.annotation.Configuration;
- 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 javax.annotation.Resource;
-
-
- @Configuration
- @EnableWebSecurity
- public class MySecurityConfig extends WebSecurityConfigurerAdapter {
-
- @Resource
- private BCryptPasswordEncoder bCryptPasswordEncoder;
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- // 允许访问"/oauth/**"路径的所有请求
- http.authorizeRequests()
- .antMatchers("/oauth/**").permitAll()
- // 其他所有请求需要进行身份验证
- .anyRequest().authenticated()
- // 允许表单登录
- .and()
- .formLogin().permitAll();
-
- // 禁用CSRF保护
- http.csrf().disable();
- }
-
- // 自定义用户的信息
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth.inMemoryAuthentication()
- // 设置用户名为"root"
- .withUser("root")
- // 设置密码为"123456",并使用BCryptPasswordEncoder进行加密
- .password(bCryptPasswordEncoder.encode("123456"))
- // 设置角色为"admin"
- .roles("admin");
- }
- }

http://localhost:8086/oauth/authorize?response_type=code&client_id=admin&scop=all
输入之后回车会跳转到登录页面
输入账号密码

账号密码就是这个

输入账号密码后跳转




http://localhost:8086/oauth/authorize?response_type=token&client_id=admin&scope=all






- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- 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.bcrypt.BCryptPasswordEncoder;
-
- import javax.annotation.Resource;
-
-
- @Configuration
- @EnableWebSecurity
- public class MySecurityConfig extends WebSecurityConfigurerAdapter {
-
- @Resource
- private BCryptPasswordEncoder bCryptPasswordEncoder;
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- // 允许访问"/oauth/**"路径的所有请求
- http.authorizeRequests()
- .antMatchers("/oauth/**").permitAll()
- // 其他所有请求需要进行身份验证
- .anyRequest().authenticated()
- // 允许表单登录
- .and()
- .formLogin().permitAll();
- // 禁用CSRF保护
- http.csrf().disable();
-
- }
-
- // 自定义用户的信息
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth.inMemoryAuthentication()
- // 设置用户名为"root"
- .withUser("root")
- // 设置密码为"123456",并使用BCryptPasswordEncoder进行加密
- .password(bCryptPasswordEncoder.encode("123456"))
- // 设置角色为"admin"
- .roles("admin");
- }
-
- // 获取认证管理器
- @Bean
- public AuthenticationManager geAuthManager() throws Exception {
- return super.authenticationManagerBean();
- }
- }

- import org.springframework.context.annotation.Configuration;
- import org.springframework.security.authentication.AuthenticationManager;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- 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 javax.annotation.Resource;
-
- @Configuration
- @EnableAuthorizationServer
- public class MyOauthConfig extends AuthorizationServerConfigurerAdapter {
-
- @Resource
- private BCryptPasswordEncoder bCryptPasswordEncoder;
-
- @Resource
- private AuthenticationManager authenticationManager;
-
- /*
- * authorization_code 授权码模式
- * password 密码模式
- * client_credentials 客户端模式
- * implicit 简单模式
- */
- @Override
- public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
-
- // 将客户端的信息配置在内存中
- clients.inMemory()
- .withClient("admin")// 客户端id
- .secret(bCryptPasswordEncoder.encode("123456"))// 客户端密码
- .redirectUris("https://www.baidu.com")// 客户端重定向地址
- .scopes("all")// 客户端授权范围
- .authorities("all")// 客户端权限
- .authorizedGrantTypes("password")// 客户端授权类型
- .autoApprove(true);// 是否自动授权
- }
-
- // 配置授权服务器的端点
- @Override
- public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
- endpoints.authenticationManager(authenticationManager);
- }
- }


修改OauthConfig配置类

- import org.springframework.context.annotation.Configuration;
- import org.springframework.security.authentication.AuthenticationManager;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- 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 javax.annotation.Resource;
-
- @Configuration
- @EnableAuthorizationServer
- public class MyOauthConfig extends AuthorizationServerConfigurerAdapter {
-
- @Resource
- private BCryptPasswordEncoder bCryptPasswordEncoder;
-
- @Resource
- private AuthenticationManager authenticationManager;
-
- /*
- * authorization_code 授权码模式
- * password 密码模式
- * client_credentials 客户端模式
- * implicit 简单模式
- */
- @Override
- public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
-
- // 将客户端的信息配置在内存中
- clients.inMemory()
- .withClient("admin")// 客户端id
- .secret(bCryptPasswordEncoder.encode("123456"))// 客户端密码
- .redirectUris("https://www.baidu.com")// 客户端重定向地址
- .scopes("all")// 客户端授权范围
- .authorities("all")// 客户端权限
- .authorizedGrantTypes("password")// 客户端授权类型
- .autoApprove(true);// 是否自动授权
- }
-
- /*
- * 配置授权服务器的端点
- */
- @Override
- public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
- endpoints.authenticationManager(authenticationManager);
- }
- /*
- * 配置授权服务器的安全性
- */
- @Override
- public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
- security.allowFormAuthenticationForClients() // 允许客户端使用表单进行身份验证
- .checkTokenAccess("permitAll()") // 检查访问令牌的访问权限,允许所有
- .tokenKeyAccess("permitAll()"); // 检查访问令牌密钥的访问权限,允许所有
- }
- }
路径
localhost:8086/oauth/check_token?


- package org.example.config;
-
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.security.authentication.AuthenticationManager;
- import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
- 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.token.TokenStore;
- import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
- import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
-
-
- import javax.annotation.Resource;
-
- @Configuration
- @EnableAuthorizationServer
- public class MyOauthConfig extends AuthorizationServerConfigurerAdapter {
-
- @Resource
- private BCryptPasswordEncoder bCryptPasswordEncoder;
-
- @Resource
- private AuthenticationManager authenticationManager;
-
- /*
- * authorization_code 授权码模式
- * password 密码模式
- * client_credentials 客户端模式
- * implicit 简单模式
- */
- @Override
- public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
-
- // 将客户端的信息配置在内存中
- clients.inMemory()
- .withClient("admin")// 客户端id
- .secret(bCryptPasswordEncoder.encode("123456"))// 客户端密码
- .redirectUris("https://www.baidu.com")// 客户端重定向地址
- .scopes("all")// 客户端授权范围
- .authorities("all")// 客户端权限
- .authorizedGrantTypes("password")// 客户端授权类型
- .autoApprove(true);// 是否自动授权
- }
-
-
- // * 配置授权服务器的端点
-
- @Override
- public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
- endpoints.authenticationManager(authenticationManager)
- .tokenStore(getTokenStore()) // token存储的地方
- .accessTokenConverter(jwtAccessTokenConverter());// 生成token的bean 解析token的bean
- }
-
- // * 配置授权服务器的安全性
-
- @Override
- public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
- security.allowFormAuthenticationForClients() // 允许客户端使用表单进行身份验证
- .checkTokenAccess("permitAll()") // 检查访问令牌的访问权限,允许所有
- .tokenKeyAccess("permitAll()"); // 检查访问令牌密钥的访问权限,允许所有
- }
-
-
- @Bean
- public TokenStore getTokenStore(){
- return new JwtTokenStore(jwtAccessTokenConverter());
- }
- /* *
- * 生成token的bean
- * 解析token的bean*/
-
- @Bean
- public JwtAccessTokenConverter jwtAccessTokenConverter(){
- JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
- jwtAccessTokenConverter.setSigningKey("asd");
- return jwtAccessTokenConverter;
- }
-
- }


修改Securityconfig类


- package org.example.config;
-
-
- import cn.hutool.http.HttpRequest;
- import cn.hutool.http.HttpResponse;
- import cn.hutool.http.HttpUtil;
- import cn.hutool.json.JSONObject;
- import cn.hutool.json.JSONUtil;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import org.example.entity.ResponseMsg;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- 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.bcrypt.BCryptPasswordEncoder;
-
- import javax.annotation.Resource;
- import javax.servlet.http.HttpServletResponse;
- import java.io.PrintWriter;
-
-
- @Configuration
- @EnableWebSecurity
- public class MySecurityConfig extends WebSecurityConfigurerAdapter {
-
- @Resource
- private BCryptPasswordEncoder bCryptPasswordEncoder;
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
-
- http.formLogin().loginProcessingUrl("/userlogin")
- .successHandler((httpServletRequest, httpServletResponse, authentication) -> {
- String username = httpServletRequest.getParameter("username");
- String password = httpServletRequest.getParameter("password");
- HttpRequest post = HttpUtil.createPost("http://localhost:8086/oauth/token");
- post.form("grant_type","password");
- post.form("client_id","admin");
- post.form("client_secret","123456");
- post.form("username",username);
- post.form("password",password);
- HttpResponse execute = post.execute();// 发送请求
- String body = execute.body();
- JSONObject entries = JSONUtil.parseObj(body);
- Object accessToken = entries.get("access_token");
- printJsonData(httpServletResponse,new ResponseMsg(200,"成功",accessToken));
- });
-
- // 允许访问"/oauth/**"路径的所有请求
- http.authorizeRequests()
- .antMatchers("/userlogin","/oauth/**").permitAll()
- // 其他所有请求需要进行身份验证
- .anyRequest().authenticated()
- // 允许表单登录
- .and()
- .formLogin().permitAll();
- // 禁用CSRF保护
- http.csrf().disable();
-
- }
-
- // 自定义用户的信息
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth.inMemoryAuthentication()
- // 设置用户名为"root"
- .withUser("root")
- // 设置密码为"123456",并使用BCryptPasswordEncoder进行加密
- .password(bCryptPasswordEncoder.encode("123456"))
- // 设置角色为"admin"
- .roles("admin");
- }
-
- // 获取认证管理器
- @Bean
- public AuthenticationManager geAuthManager() throws Exception {
- return super.authenticationManagerBean();
- }
-
- public void printJsonData(HttpServletResponse response, ResponseMsg responseMsg) {
- try {
- response.setContentType("application/json;charset=utf8");
- ObjectMapper objectMapper = new ObjectMapper();
- String s = objectMapper.writeValueAsString(responseMsg);
- PrintWriter writer = response.getWriter();
- writer.print(s);
- writer.flush();
- writer.close();
- }catch (Exception e){
- e.printStackTrace();
-
- }
- }
-
- }
访问

写一个order
写一个配置类

- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
- import org.springframework.security.config.annotation.web.builders.HttpSecurity;
- import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
- import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
- import org.springframework.security.oauth2.provider.token.TokenStore;
- import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
- import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
-
-
- @Configuration
- @EnableResourceServer
- @EnableGlobalMethodSecurity(jsr250Enabled = true,prePostEnabled = true,securedEnabled=true)
- public class MySecurityConfig extends WebSecurityConfigurerAdapter {
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http.authorizeRequests()
- // 其他所有请求需要进行身份验证
- .anyRequest().authenticated()
- // 允许表单登录
- .and()
- .formLogin().permitAll();
- // 禁用CSRF保护
- http.csrf().disable();
-
- }
- @Bean
- public TokenStore getTokenStore(){
- return new JwtTokenStore(jwtAccessTokenConverter());
- }
- @Bean
- public JwtAccessTokenConverter jwtAccessTokenConverter(){
- JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
- jwtAccessTokenConverter.setSigningKey("root");
- return jwtAccessTokenConverter;
- }
-
- }
controller
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- @RestController
- @RequestMapping("/test")
- public class TestController {
- @GetMapping
- public String test(){
- return "成功";
- }
- }
resouce配置文件


测试

