本文共 7841 字,大约阅读时间需要 26 分钟。
在本文中,我们将详细讲解如何在Spring Boot项目中使用JDBC存储OAuth2.0的令牌。之前的一篇文章中,我们讨论了使用Redis的实现方式,本文将深入探讨JDBC的存储方式,使用Spring Boot和相关技术栈进行实现。
首先,我们需要创建两个主要服务:认证服务器(javayh-server
)和资源服务器(javayh-resource
)。这两者可以是同一台服务器,也可以是不同的服务器。
认证服务器负责处理OAuth2.0的授权流程,而资源服务器负责存储和管理用户的资源。通过这样的分离,我们可以更好地实现松耦合的设计。
下面是核心依赖:
org.springframework.cloud spring-cloud-starter-oauth2 org.springframework.boot spring-boot-starter-jdbc org.apache.tomcat tomcat-jdbc org.springframework.boot spring-boot-starter-aop org.mybatis.springboot mybatis-spring-boot-starter ${mybatis.version} com.alibaba druid-spring-boot-starter ${druid.version} mysql mysql-connector-java ${mysql.connector.version} com.github.pagehelper pagehelper-spring-boot-starter ${pagehelpe.version}
由于SQL脚本篇幅较长,已放在另一个文档中。点击查看详情。
在认证服务器进行配置,设置如下:
@Configuration@EnableAuthorizationServerpublic class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { @Autowired(required = false) private AuthenticationManager authenticationManager; @Autowired private DataSource dataSource; @Autowired @Qualifier("userDetailsServiceImpl") private UserDetailsService userDetailsService; @Bean public ClientDetailsService clientDetails() { JdbcClientDetailsService jdbcClientDetailsService = new JdbcClientDetailsService(dataSource); jdbcClientDetailsService.setPasswordEncoder(new BCryptPasswordEncoder()); return jdbcClientDetailsService; } @Bean public TokenStore tokenStore() { return new JdbcTokenStore(dataSource); } @Bean public ApprovalStore approvalStore() { return new JdbcApprovalStore(dataSource); } @Bean public TokenEnhancer tokenEnhancer() { return new BaseTokenEnhancer(); } @Bean public AuthorizationCodeServices authorizationCodeServices() { return new JdbcAuthorizationCodeServices(dataSource); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.jdbc(dataSource); clients.withClientDetails(clientDetails()); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST) .authenticationManager(authenticationManager) .approvalStore(approvalStore()) .userDetailsService(userDetailsService) .tokenServices(createDefaultTokenServices()) .accessTokenConverter(SecurityHelper.buildAccessTokenConverter()) .tokenStore(tokenStore()) .authorizationCodeServices(authorizationCodeServices()); } private DefaultTokenServices createDefaultTokenServices() { DefaultTokenServices tokenServices = new DefaultTokenServices(); tokenServices.setTokenStore(tokenStore()); tokenServices.setTokenEnhancer(tokenEnhancer()); tokenServices.setSupportRefreshToken(true); tokenServices.setReuseRefreshToken(true); tokenServices.setClientDetailsService(clientDetails()); return tokenServices; } @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security .checkTokenAccess("isAuthenticated()") .allowFormAuthenticationForClients() .checkTokenAccess("permitAll()"); }}
服务器安全配置如下:
package com.javayh.oauth2.server.conf;import com.javayh.oauth2.server.conf.service.UserDetailsServiceImpl;import lombok.extern.slf4j.Slf4j;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;import org.springframework.security.config.annotation.web.builders.WebSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;@Slf4j@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity( prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { @Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public UserDetailsService userDetailsService() { return new UserDetailsServiceImpl(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService()); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring() .antMatchers("/oauth/check_token"); }}
资源服务器配置如下:
package com.javayh.resource.conf;import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;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.configurers.ExpressionUrlAuthorizationConfigurer;import org.springframework.security.config.http.SessionCreationPolicy;import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;@Configuration@EnableResourceServer@EnableGlobalMethodSecurity( prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry = http .antMatcher("/**") .authorizeRequests(); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) .and() .authorizeRequests() .requestMatchers(EndpointRequest.toAnyEndpoint()) .permitAll().anyRequest() .authenticated() .and() .exceptionHandling() .accessDeniedHandler(new AccessDeniedHandler()) .authenticationEntryPoint(new WebException()) .and() .cors() .and() .csrf().disable() .httpBasic().disable(); }}
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" \-d "username=admin&password=123456" \"http://localhost:9090/oauth/token"
可以通过两种方式获取资源:
curl -X GET -H "Authorization: Bearer access_token" \"http://localhost:9090/resources"
curl -X GET \-H "Authorization: Bearer access_token" \"http://localhost:9090/resources"
希望这篇文章对您理解OAuth2.0在Spring Boot项目中基于JDBC存储令牌的实现方式有所帮助。如果您对某些技术细节有疑问或者需要进一步的帮助,请随时通过评论或联系我(微信:372787553)进行交流。
关注 Java有货
领取更多技术文章,如遇问题欢迎加入开发者交流群,共同进步!
转载地址:http://jidpz.baihongyu.com/