当前位置:   article > 正文

SpringBoot整合OAuth2.0看完你就会了!_springboot oauth2.0

springboot oauth2.0

OAuth 2.0是一种开放的授权协议,它允许用户授权第三方应用访问其账户(或资源),而无需共享其用户账户凭据。在Spring Boot中,我们可以使用Spring Security的OAuth2.0模块来实现授权验证。

依赖引入

配置认证服务器

  1. /**
  2. * @author Charles
  3. * @module springboot
  4. * @since 2023/6/19 16:30
  5. */
  6. @Configuration
  7. @EnableAuthorizationServer //开启认证服务器
  8. public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
  9. //在 MyOAuth2Config 添加到容器了
  10. @Autowired
  11. private PasswordEncoder passwordEncoder;
  12. @Autowired
  13. private AuthenticationManager authenticationManager;
  14. @Autowired
  15. private MyUserDetailsService myUserDetailsService;
  16. @Autowired
  17. @Qualifier("jwtTokenStore")
  18. TokenStore jwtTokenStore;
  19. @Autowired
  20. JwtAccessTokenConverter jwtAccessTokenConverter;
  21. @Autowired
  22. TokenEnhancerChain tokenEnhancerChain;
  23. /**
  24. * 配置被允许访问此认证服务器的客户端详细信息
  25. * 1.内存管理
  26. * 2.数据库管理方式
  27. * @param clients
  28. * @throws Exception
  29. */
  30. @Override
  31. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  32. clients.inMemory()
  33. //客户端名称
  34. .withClient("test-pc")
  35. //客户端密码
  36. .secret(passwordEncoder.encode("123456"))
  37. //资源id,商品资源
  38. .resourceIds("oauth2-server")
  39. //授权类型, 可同时支持多种授权类型
  40. .authorizedGrantTypes("authorization_code", "password", "implicit","client_credentials","refresh_token")
  41. //授权范围标识,哪部分资源可访问(all是标识,不是代表所有)
  42. .scopes("all")
  43. //false 跳转到授权页面手动点击授权,true 不用手动授权,直接响应授权码
  44. .autoApprove(false)
  45. //客户端回调地址
  46. .redirectUris("http://www.baidu.com/")
  47. ;
  48. }
  49. @Override
  50. public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
  51. //密码模式需要配置认证管理器
  52. endpoints.authenticationManager(authenticationManager);
  53. //刷新令牌获取新令牌时需要
  54. endpoints.userDetailsService(myUserDetailsService);
  55. endpoints.tokenEnhancer(tokenEnhancerChain);
  56. //令牌管理策略
  57. // endpoints.tokenStore(tokenStore);
  58. //设置为jwt存储
  59. endpoints.tokenStore(jwtTokenStore);
  60. endpoints.accessTokenConverter(jwtAccessTokenConverter);
  61. //授权码管理策略,针对授权码模式有效,会将授权码放到 auth_code 表,授权后就会删除它
  62. //endpoints.authorizationCodeServices(jdbcAuthorizationCodeServices);
  63. DefaultTokenServices tokenService = getTokenStore(endpoints);
  64. endpoints.tokenServices(tokenService);
  65. }
  66. //配置TokenService参数
  67. private DefaultTokenServices getTokenStore(AuthorizationServerEndpointsConfigurer endpoints) {
  68. DefaultTokenServices tokenService = new DefaultTokenServices();
  69. tokenService.setTokenStore(endpoints.getTokenStore());
  70. tokenService.setSupportRefreshToken(true);
  71. tokenService.setClientDetailsService(endpoints.getClientDetailsService());
  72. tokenService.setTokenEnhancer(endpoints.getTokenEnhancer());
  73. //token有效期 1小时
  74. tokenService.setAccessTokenValiditySeconds(3600);
  75. //token刷新有效期 15
  76. tokenService.setRefreshTokenValiditySeconds(3600 * 12 * 15);
  77. tokenService.setReuseRefreshToken(false);
  78. return tokenService;
  79. }
  80. /**
  81. * 解决访问/oauth/check_token 403的问题
  82. *
  83. * @param security
  84. * @throws Exception
  85. */
  86. @Override
  87. public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
  88. // 允许表单认证
  89. security
  90. .tokenKeyAccess("permitAll()")
  91. .checkTokenAccess("permitAll()")
  92. .allowFormAuthenticationForClients();
  93. }

配置资源服务器

  1. /**
  2. * @author Charles
  3. * @module springboot
  4. * @since 2023/6/20 12:14
  5. */
  6. @Configuration
  7. @EnableResourceServer
  8. @EnableGlobalMethodSecurity(prePostEnabled = true)
  9. public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {
  10. @Autowired
  11. @Qualifier("jwtTokenStore")
  12. TokenStore jwtTokenStore;
  13. @Override
  14. public void configure(HttpSecurity http) throws Exception {
  15. http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
  16. .and()
  17. .authorizeRequests()
  18. //.authorizeRequests(request -> request.anyRequest().access("@checker.check(authentication,request)"))
  19. //.and()
  20. //放行
  21. .antMatchers("/oauth/**","/login/**","/logout/**", "/sse/**").permitAll()
  22. //其他路径需要role_admin
  23. .anyRequest().hasAnyAuthority("role_admin")
  24. .and()
  25. //表单提交放行
  26. .formLogin().permitAll()
  27. .and()
  28. //csrf关闭
  29. .exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {
  30. @Override
  31. public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
  32. System.out.println(accessDeniedException);
  33. }
  34. });
  35. }
  36. @Override
  37. public void configure(ResourceServerSecurityConfigurer resources) {
  38. resources.resourceId("oauth2-server")
  39. .tokenServices(tokenDefaultServices());
  40. }
  41. /**
  42. * 配置资源服务器如何校验token
  43. * 1. DefaultTokenServices
  44. * 如果认证服务器和资源服务器在同一个服务,则直接采用默认服务验证
  45. * 2.RemoteTokenServices
  46. * 当认证服务器和资源服务器不在同一个服务,要使用此服务器去远程认证服务器验证
  47. * @return
  48. */
  49. @Primary
  50. @Bean
  51. public DefaultTokenServices tokenDefaultServices() {
  52. DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
  53. defaultTokenServices.setTokenStore(jwtTokenStore);
  54. defaultTokenServices.setSupportRefreshToken(true);
  55. return defaultTokenServices;
  56. }
  57. // @Primary
  58. // @Bean
  59. // public RemoteTokenServices tokenServices() {
  60. // //资源服务器去远程认证服务器验证 token 是否有效
  61. // final RemoteTokenServices tokenService = new RemoteTokenServices();
  62. // //请求认证服务器验证URL,注意:默认这个端点是拒绝访问的,要设置认证后可访问
  63. // tokenService.setCheckTokenEndpointUrl("http://localhost:8899/oauth/check_token");
  64. // //在认证服务器配置的客户端id
  65. // tokenService.setClientId("test-pc");
  66. // //在认证服务器配置的客户端密码
  67. // tokenService.setClientSecret("123456");
  68. // return tokenService;
  69. // }
  70. }

token配置

  1. /**
  2. * @author Charles
  3. * @module springboot
  4. * @since 2023/6/20 15:25
  5. */
  6. @Configuration
  7. public class JwtTokenStoreConfig {
  8. @Autowired
  9. private CustomTokenEnhancer customTokenEnhancer;
  10. @Value("${privateKey}")
  11. private String privateKey;
  12. @Value("${password}")
  13. private String password;
  14. @Value("${alias}")
  15. private String alias;
  16. @Bean
  17. public JwtAccessTokenConverter jwtAccessTokenConverter(){
  18. JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
  19. KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource(privateKey), password.toCharArray());
  20. jwtAccessTokenConverter.setKeyPair(keyStoreKeyFactory.getKeyPair(alias));
  21. return jwtAccessTokenConverter;
  22. }
  23. @Bean("jwtTokenStore")
  24. public TokenStore jwtTokenStore(){
  25. JwtTokenStore jwtTokenStore = new JwtTokenStore(jwtAccessTokenConverter());
  26. return jwtTokenStore;
  27. }
  28. @Bean
  29. public TokenEnhancerChain tokenEnhancerChain() {
  30. TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
  31. List<TokenEnhancer> enhancers = new ArrayList<>();
  32. enhancers.add(jwtAccessTokenConverter());
  33. enhancers.add(customTokenEnhancer);
  34. //将自定义Enhancer加入EnhancerChain的delegates数组中
  35. enhancerChain.setTokenEnhancers(enhancers);
  36. return enhancerChain;
  37. }
  38. private static final KeyStore JKS_STORE;
  39. static {
  40. try {
  41. JKS_STORE = KeyStore.getInstance("jks");
  42. } catch (KeyStoreException e) {
  43. throw new RuntimeException("can not obtain jks keystore instance");
  44. }
  45. }
  46. @Bean
  47. @ConditionalOnMissingBean
  48. @SneakyThrows
  49. public JWKSource<SecurityContext> jwkSource() {
  50. ClassPathResource classPathResource = new ClassPathResource(privateKey);
  51. char[] pin = password.toCharArray();
  52. JKS_STORE.load(classPathResource.getInputStream(), pin);
  53. RSAKey rsaKey = RSAKey.load(JKS_STORE, alias, pin);
  54. JWKSet jwkSet = new JWKSet(rsaKey);
  55. return new ImmutableJWKSet<>(jwkSet);
  56. }

配置UserDetailsService

  1. /**
  2. * @author Charles
  3. * @module springboot
  4. * @since 2023/6/20 11:47
  5. */
  6. @Component
  7. public class MyUserDetailsService implements UserDetailsService {
  8. @Autowired
  9. private PasswordEncoder passwordEncoder;
  10. @Override
  11. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  12. return new User("admin", passwordEncoder.encode("123456"),
  13. AuthorityUtils.createAuthorityList("role_admin"));
  14. }
  15. }

好了到此为止,以上就是springboot整合ouath2.0的主要代码啦,欢迎大家在评论区留言讨论!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/505751
推荐阅读
相关标签
  

闽ICP备14008679号