• OAuth2


    一、介绍

    OAuth2是目前最流行的授权机制,用来授权第三方应用,获取用户数据。允许用户授权B应用不提供帐号密码的方式去访问该用户在A应用服务器上的某些特定资源。

    资源所有者(Resource Owner):拥有受保护资源(如用户资料、照片、视频等)的用户。
    客户端(Client):想要访问资源所有者资源的第三方应用程序。
    授权服务器(Authorization Server):处理客户端的授权请求并发放访问令牌。
    资源服务器(Resource Server):存储受保护的资源,并在访问令牌的授权下提供资源。
    访问令牌(Access Token):授权服务器发放的用于访问资源的令牌。
    回调URL(Callback URL):客户端在申请授权时提供的 URL,用于在授权成功后将访问令牌发送给客户端。

    二、oauth2.0四个角色

    资源所有者(Resource Owner):这是拥有受保护资源的用户。例如,一个用户可能有存储在云服务提供商的文件。
    授权服务器(Authorization Server):这是处理请求和响应的中央服务器。它授权客户端访问资源所有者的资源。
    资源服务器(Resource Server):这是存储和提供受保护资源的服务器。例如,云服务提供商可能会有一个资源服务器,它存储用户的文件。
    客户端(Client):这是想要访问资源所有者的资源的客户端应用程序。例如,一个云存储同步工具的移动应用程序可能会扮演客户端的角色。

    三、四种授权模式

    授权码(Authorization Code):
    客户端向资源所有者请求授权。
    资源所有者同意授权,并返回一个授权码。
    客户端使用授权码向授权服务器请求访问令牌。
    授权服务器验证授权码,并发放访问令牌。
    隐藏式(Implicit):
    客户端直接向资源服务器请求受保护的资源,并在 URL 中携带访问令牌。
    资源服务器验证访问令牌,并响应请求。
    密码式(Password):
    客户端使用资源所有者的用户名和密码向授权服务器请求访问令牌。
    授权服务器验证用户名和密码,并发放访问令牌。
    客户端凭证(Client Credentials):
    客户端使用其客户端凭证(如客户端ID和客户端密钥)向授权服务器请求访问令牌。
    授权服务器验证客户端凭证,并发放访问令牌。
    在实际应用中,根据应用程序的需求和安全性要求,开发人员可以选择适当的授权模式。对于Web应用程序,通常使用授权码或隐藏式;对于移动应用程序,通常使用隐藏式或客户端凭证。密码式通常不推荐使用,因为它可能会导致密码泄露。

    四、OAUTH2的spring cloud 微服务单点登录

    用户:就是注册的用户

    客户端:就是我们的前端项目

    授权服务器:我们可以专门在后台创建一个专门管授权的微服务

    资源微服务:像其他的订单微服务,什么搜索微服务拉都可以看做用户能够访问的资源

    五、spring cloud alibaba 使用oauth2

    1. 创建父项目

    2. 启动nacos

    3. 导入依赖

    1. <dependency>
    2. <groupId>org.springframework.security.oauthgroupId>
    3. <artifactId>spring-security-oauth2artifactId>
    4. <version>2.3.5.RELEASEversion>
    5. dependency>
    6. <dependency>
    7. <groupId>org.springframework.securitygroupId>
    8. <artifactId>spring-security-jwtartifactId>
    9. <version>1.1.0.RELEASEversion>
    10. dependency>
    11. <dependency>
    12. <groupId>org.springframework.cloudgroupId>
    13. <artifactId>spring-cloud-starter-openfeignartifactId>
    14. dependency>

    六、授权码模式测试

    1. 启动类中加入BCryptPasswordEncoder 

            

    1. @Bean
    2. public BCryptPasswordEncoder bCryptPasswordEncoder(){
    3. return new BCryptPasswordEncoder();
    4. }

    2. 写一个OauthConfig配置类

    1. import org.springframework.context.annotation.Configuration;
    2. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    3. import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
    4. import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
    5. import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
    6. import javax.annotation.Resource;
    7. @Configuration
    8. @EnableAuthorizationServer
    9. public class MyOauthConfig extends AuthorizationServerConfigurerAdapter {
    10. @Resource
    11. private BCryptPasswordEncoder bCryptPasswordEncoder;
    12. /*
    13. * authorization_code 授权码模式
    14. * password 密码模式
    15. * client_credentials 客户端模式
    16. * implicit 简单模式
    17. */
    18. @Override
    19. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    20. // 将客户端的信息配置在内存中
    21. clients.inMemory()
    22. .withClient("admin")// 客户端id
    23. .secret(bCryptPasswordEncoder.encode("123456"))// 客户端密码
    24. .redirectUris("https://www.baidu.com")// 客户端重定向地址
    25. .scopes("all")// 客户端授权范围
    26. .authorities("all")// 客户端权限
    27. .authorizedGrantTypes("authorization_code")// 客户端授权类型
    28. .autoApprove(true);// 是否自动授权
    29. }
    30. }

    3.写一个security配置类

    1. import org.springframework.context.annotation.Configuration;
    2. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    3. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    4. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    5. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    6. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    7. import javax.annotation.Resource;
    8. @Configuration
    9. @EnableWebSecurity
    10. public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    11. @Resource
    12. private BCryptPasswordEncoder bCryptPasswordEncoder;
    13. @Override
    14. protected void configure(HttpSecurity http) throws Exception {
    15. // 允许访问"/oauth/**"路径的所有请求
    16. http.authorizeRequests()
    17. .antMatchers("/oauth/**").permitAll()
    18. // 其他所有请求需要进行身份验证
    19. .anyRequest().authenticated()
    20. // 允许表单登录
    21. .and()
    22. .formLogin().permitAll();
    23. // 禁用CSRF保护
    24. http.csrf().disable();
    25. }
    26. // 自定义用户的信息
    27. @Override
    28. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    29. auth.inMemoryAuthentication()
    30. // 设置用户名为"root"
    31. .withUser("root")
    32. // 设置密码为"123456",并使用BCryptPasswordEncoder进行加密
    33. .password(bCryptPasswordEncoder.encode("123456"))
    34. // 设置角色为"admin"
    35. .roles("admin");
    36. }
    37. }

    4. 配置端口号

    5. 申请授权码 

    http://localhost:8086/oauth/authorize?response_type=code&client_id=admin&scop=all

     输入之后回车会跳转到登录页面

    输入账号密码

     账号密码就是这个

     输入账号密码后跳转

    6. 根据授权码生成token 

    七、简单模式测试

    1. 修改OauthConfig的配置类

    2. 访问地址

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

     

    八、客户端模式测试

    1. 修改OauthConfig的配置类

    2. 访问

    九、密码模式测试

    1. 修改SecurityConfig的配置类

    1. import org.springframework.context.annotation.Bean;
    2. import org.springframework.context.annotation.Configuration;
    3. import org.springframework.security.authentication.AuthenticationManager;
    4. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    5. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    6. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    7. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    8. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    9. import javax.annotation.Resource;
    10. @Configuration
    11. @EnableWebSecurity
    12. public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    13. @Resource
    14. private BCryptPasswordEncoder bCryptPasswordEncoder;
    15. @Override
    16. protected void configure(HttpSecurity http) throws Exception {
    17. // 允许访问"/oauth/**"路径的所有请求
    18. http.authorizeRequests()
    19. .antMatchers("/oauth/**").permitAll()
    20. // 其他所有请求需要进行身份验证
    21. .anyRequest().authenticated()
    22. // 允许表单登录
    23. .and()
    24. .formLogin().permitAll();
    25. // 禁用CSRF保护
    26. http.csrf().disable();
    27. }
    28. // 自定义用户的信息
    29. @Override
    30. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    31. auth.inMemoryAuthentication()
    32. // 设置用户名为"root"
    33. .withUser("root")
    34. // 设置密码为"123456",并使用BCryptPasswordEncoder进行加密
    35. .password(bCryptPasswordEncoder.encode("123456"))
    36. // 设置角色为"admin"
    37. .roles("admin");
    38. }
    39. // 获取认证管理器
    40. @Bean
    41. public AuthenticationManager geAuthManager() throws Exception {
    42. return super.authenticationManagerBean();
    43. }
    44. }

    2. 修改OauthConfig配置类

    1. import org.springframework.context.annotation.Configuration;
    2. import org.springframework.security.authentication.AuthenticationManager;
    3. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    4. import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
    5. import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
    6. import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
    7. import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
    8. import javax.annotation.Resource;
    9. @Configuration
    10. @EnableAuthorizationServer
    11. public class MyOauthConfig extends AuthorizationServerConfigurerAdapter {
    12. @Resource
    13. private BCryptPasswordEncoder bCryptPasswordEncoder;
    14. @Resource
    15. private AuthenticationManager authenticationManager;
    16. /*
    17. * authorization_code 授权码模式
    18. * password 密码模式
    19. * client_credentials 客户端模式
    20. * implicit 简单模式
    21. */
    22. @Override
    23. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    24. // 将客户端的信息配置在内存中
    25. clients.inMemory()
    26. .withClient("admin")// 客户端id
    27. .secret(bCryptPasswordEncoder.encode("123456"))// 客户端密码
    28. .redirectUris("https://www.baidu.com")// 客户端重定向地址
    29. .scopes("all")// 客户端授权范围
    30. .authorities("all")// 客户端权限
    31. .authorizedGrantTypes("password")// 客户端授权类型
    32. .autoApprove(true);// 是否自动授权
    33. }
    34. // 配置授权服务器的端点
    35. @Override
    36. public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    37. endpoints.authenticationManager(authenticationManager);
    38. }
    39. }

    3.访问

    4. 不用输入第三方的用户名和密码

    修改OauthConfig配置类

    1. import org.springframework.context.annotation.Configuration;
    2. import org.springframework.security.authentication.AuthenticationManager;
    3. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    4. import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
    5. import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
    6. import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
    7. import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
    8. import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
    9. import javax.annotation.Resource;
    10. @Configuration
    11. @EnableAuthorizationServer
    12. public class MyOauthConfig extends AuthorizationServerConfigurerAdapter {
    13. @Resource
    14. private BCryptPasswordEncoder bCryptPasswordEncoder;
    15. @Resource
    16. private AuthenticationManager authenticationManager;
    17. /*
    18. * authorization_code 授权码模式
    19. * password 密码模式
    20. * client_credentials 客户端模式
    21. * implicit 简单模式
    22. */
    23. @Override
    24. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    25. // 将客户端的信息配置在内存中
    26. clients.inMemory()
    27. .withClient("admin")// 客户端id
    28. .secret(bCryptPasswordEncoder.encode("123456"))// 客户端密码
    29. .redirectUris("https://www.baidu.com")// 客户端重定向地址
    30. .scopes("all")// 客户端授权范围
    31. .authorities("all")// 客户端权限
    32. .authorizedGrantTypes("password")// 客户端授权类型
    33. .autoApprove(true);// 是否自动授权
    34. }
    35. /*
    36. * 配置授权服务器的端点
    37. */
    38. @Override
    39. public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    40. endpoints.authenticationManager(authenticationManager);
    41. }
    42. /*
    43. * 配置授权服务器的安全性
    44. */
    45. @Override
    46. public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    47. security.allowFormAuthenticationForClients() // 允许客户端使用表单进行身份验证
    48. .checkTokenAccess("permitAll()") // 检查访问令牌的访问权限,允许所有
    49. .tokenKeyAccess("permitAll()"); // 检查访问令牌密钥的访问权限,允许所有
    50. }
    51. }

    5. 校验token

    路径

    localhost:8086/oauth/check_token?


    6. 手动生成Token,解析Token

    1. package org.example.config;
    2. import org.springframework.context.annotation.Bean;
    3. import org.springframework.context.annotation.Configuration;
    4. import org.springframework.security.authentication.AuthenticationManager;
    5. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    6. import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
    7. import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
    8. import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
    9. import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
    10. import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
    11. import org.springframework.security.oauth2.provider.token.TokenStore;
    12. import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
    13. import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
    14. import javax.annotation.Resource;
    15. @Configuration
    16. @EnableAuthorizationServer
    17. public class MyOauthConfig extends AuthorizationServerConfigurerAdapter {
    18. @Resource
    19. private BCryptPasswordEncoder bCryptPasswordEncoder;
    20. @Resource
    21. private AuthenticationManager authenticationManager;
    22. /*
    23. * authorization_code 授权码模式
    24. * password 密码模式
    25. * client_credentials 客户端模式
    26. * implicit 简单模式
    27. */
    28. @Override
    29. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    30. // 将客户端的信息配置在内存中
    31. clients.inMemory()
    32. .withClient("admin")// 客户端id
    33. .secret(bCryptPasswordEncoder.encode("123456"))// 客户端密码
    34. .redirectUris("https://www.baidu.com")// 客户端重定向地址
    35. .scopes("all")// 客户端授权范围
    36. .authorities("all")// 客户端权限
    37. .authorizedGrantTypes("password")// 客户端授权类型
    38. .autoApprove(true);// 是否自动授权
    39. }
    40. // * 配置授权服务器的端点
    41. @Override
    42. public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    43. endpoints.authenticationManager(authenticationManager)
    44. .tokenStore(getTokenStore()) // token存储的地方
    45. .accessTokenConverter(jwtAccessTokenConverter());// 生成token的bean 解析token的bean
    46. }
    47. // * 配置授权服务器的安全性
    48. @Override
    49. public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    50. security.allowFormAuthenticationForClients() // 允许客户端使用表单进行身份验证
    51. .checkTokenAccess("permitAll()") // 检查访问令牌的访问权限,允许所有
    52. .tokenKeyAccess("permitAll()"); // 检查访问令牌密钥的访问权限,允许所有
    53. }
    54. @Bean
    55. public TokenStore getTokenStore(){
    56. return new JwtTokenStore(jwtAccessTokenConverter());
    57. }
    58. /* *
    59. * 生成token的bean
    60. * 解析token的bean*/
    61. @Bean
    62. public JwtAccessTokenConverter jwtAccessTokenConverter(){
    63. JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
    64. jwtAccessTokenConverter.setSigningKey("asd");
    65. return jwtAccessTokenConverter;
    66. }
    67. }

    7.自定义登陆

    修改Securityconfig类

    1. package org.example.config;
    2. import cn.hutool.http.HttpRequest;
    3. import cn.hutool.http.HttpResponse;
    4. import cn.hutool.http.HttpUtil;
    5. import cn.hutool.json.JSONObject;
    6. import cn.hutool.json.JSONUtil;
    7. import com.fasterxml.jackson.databind.ObjectMapper;
    8. import org.example.entity.ResponseMsg;
    9. import org.springframework.context.annotation.Bean;
    10. import org.springframework.context.annotation.Configuration;
    11. import org.springframework.security.authentication.AuthenticationManager;
    12. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    13. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    14. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    15. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    16. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    17. import javax.annotation.Resource;
    18. import javax.servlet.http.HttpServletResponse;
    19. import java.io.PrintWriter;
    20. @Configuration
    21. @EnableWebSecurity
    22. public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    23. @Resource
    24. private BCryptPasswordEncoder bCryptPasswordEncoder;
    25. @Override
    26. protected void configure(HttpSecurity http) throws Exception {
    27. http.formLogin().loginProcessingUrl("/userlogin")
    28. .successHandler((httpServletRequest, httpServletResponse, authentication) -> {
    29. String username = httpServletRequest.getParameter("username");
    30. String password = httpServletRequest.getParameter("password");
    31. HttpRequest post = HttpUtil.createPost("http://localhost:8086/oauth/token");
    32. post.form("grant_type","password");
    33. post.form("client_id","admin");
    34. post.form("client_secret","123456");
    35. post.form("username",username);
    36. post.form("password",password);
    37. HttpResponse execute = post.execute();// 发送请求
    38. String body = execute.body();
    39. JSONObject entries = JSONUtil.parseObj(body);
    40. Object accessToken = entries.get("access_token");
    41. printJsonData(httpServletResponse,new ResponseMsg(200,"成功",accessToken));
    42. });
    43. // 允许访问"/oauth/**"路径的所有请求
    44. http.authorizeRequests()
    45. .antMatchers("/userlogin","/oauth/**").permitAll()
    46. // 其他所有请求需要进行身份验证
    47. .anyRequest().authenticated()
    48. // 允许表单登录
    49. .and()
    50. .formLogin().permitAll();
    51. // 禁用CSRF保护
    52. http.csrf().disable();
    53. }
    54. // 自定义用户的信息
    55. @Override
    56. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    57. auth.inMemoryAuthentication()
    58. // 设置用户名为"root"
    59. .withUser("root")
    60. // 设置密码为"123456",并使用BCryptPasswordEncoder进行加密
    61. .password(bCryptPasswordEncoder.encode("123456"))
    62. // 设置角色为"admin"
    63. .roles("admin");
    64. }
    65. // 获取认证管理器
    66. @Bean
    67. public AuthenticationManager geAuthManager() throws Exception {
    68. return super.authenticationManagerBean();
    69. }
    70. public void printJsonData(HttpServletResponse response, ResponseMsg responseMsg) {
    71. try {
    72. response.setContentType("application/json;charset=utf8");
    73. ObjectMapper objectMapper = new ObjectMapper();
    74. String s = objectMapper.writeValueAsString(responseMsg);
    75. PrintWriter writer = response.getWriter();
    76. writer.print(s);
    77. writer.flush();
    78. writer.close();
    79. }catch (Exception e){
    80. e.printStackTrace();
    81. }
    82. }
    83. }

    访问

    8.order

    写一个order

    写一个配置类

    1. import org.springframework.context.annotation.Bean;
    2. import org.springframework.context.annotation.Configuration;
    3. import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    4. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    5. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    6. import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
    7. import org.springframework.security.oauth2.provider.token.TokenStore;
    8. import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
    9. import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
    10. @Configuration
    11. @EnableResourceServer
    12. @EnableGlobalMethodSecurity(jsr250Enabled = true,prePostEnabled = true,securedEnabled=true)
    13. public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    14. @Override
    15. protected void configure(HttpSecurity http) throws Exception {
    16. http.authorizeRequests()
    17. // 其他所有请求需要进行身份验证
    18. .anyRequest().authenticated()
    19. // 允许表单登录
    20. .and()
    21. .formLogin().permitAll();
    22. // 禁用CSRF保护
    23. http.csrf().disable();
    24. }
    25. @Bean
    26. public TokenStore getTokenStore(){
    27. return new JwtTokenStore(jwtAccessTokenConverter());
    28. }
    29. @Bean
    30. public JwtAccessTokenConverter jwtAccessTokenConverter(){
    31. JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
    32. jwtAccessTokenConverter.setSigningKey("root");
    33. return jwtAccessTokenConverter;
    34. }
    35. }

    controller

    1. import org.springframework.web.bind.annotation.GetMapping;
    2. import org.springframework.web.bind.annotation.RequestMapping;
    3. import org.springframework.web.bind.annotation.RestController;
    4. @RestController
    5. @RequestMapping("/test")
    6. public class TestController {
    7. @GetMapping
    8. public String test(){
    9. return "成功";
    10. }
    11. }

    resouce配置文件

    测试

  • 相关阅读:
    V5.1.1,新版发布|软件安全大于一切
    php沿河农产品特卖网站的设计与实现毕业设计源码201524
    再次安装pytorch
    corosync-qdevice使用
    【LeetCode每日一题】——70.爬楼梯
    Android Studio展示Activty生命周期
    Linux | gdb的基本使用
    C# WPF入门学习主线篇(六)—— TextBox常见属性和事件
    JAVA面试题之高级常问必问
    看了两位阿里P10的成长经历,我的认知升华了
  • 原文地址:https://blog.csdn.net/weixin_68193389/article/details/134530829