博客
关于我
SpringCloud+OAuth2实现统一权限验证,并持久化到Mysql中
阅读量:571 次
发布时间:2019-03-09

本文共 7985 字,大约阅读时间需要 26 分钟。

OAuth2.0 基于JDBC实现

在本文中,我们将详细讲解如何在Spring Boot项目中使用JDBC存储OAuth2.0的令牌。之前的一篇文章中,我们讨论了使用Redis的实现方式,本文将深入探讨JDBC的存储方式,使用Spring Boot和相关技术栈进行实现。

项目搭建

1. 创建服务

首先,我们需要创建两个主要服务:认证服务器(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}

2. 数据库脚本

由于SQL脚本篇幅较长,已放在另一个文档中。点击查看详情。

认证服务器配置

1. 统一认证处理

在认证服务器进行配置,设置如下:

@Configuration
@EnableAuthorizationServer
public 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()");
}
}

2. 服务器安全配置

服务器安全配置如下:

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();
}
}

调用流程

1. 获取token

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" \
-d "username=admin&password=123456" \
"http://localhost:9090/oauth/token"

2. 获取资源

可以通过两种方式获取资源:

  • 使用 access_token:
  • curl -X GET -H "Authorization: Bearer access_token" \
    "http://localhost:9090/resources"
    1. 使用 Authorization header:
    2. curl -X GET \
      -H "Authorization: Bearer access_token" \
      "http://localhost:9090/resources"

      结语

      希望这篇文章对您理解OAuth2.0在Spring Boot项目中基于JDBC存储令牌的实现方式有所帮助。如果您对某些技术细节有疑问或者需要进一步的帮助,请随时通过评论或联系我(微信:372787553)进行交流。

      关注 Java有货 领取更多技术文章,如遇问题欢迎加入开发者交流群,共同进步!

    转载地址:http://jidpz.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现knapsack背包问题算法(附完整源码)
    查看>>
    Objective-C实现knapsack背包问题算法(附完整源码)
    查看>>
    Objective-C实现knight tour骑士之旅算法(附完整源码)
    查看>>
    Objective-C实现KNN算法(附完整源码)
    查看>>
    Objective-C实现koch snowflake科赫雪花算法(附完整源码)
    查看>>
    Objective-C实现KPCA(附完整源码)
    查看>>
    Objective-C实现kth order statistick阶统计量算法(附完整源码)
    查看>>
    Objective-C实现LongestIncreasingSubsequence最长递增子序列算法(附完整源码)
    查看>>
    Objective-C实现LRU 缓存算法(附完整源码)
    查看>>
    Objective-C实现lstm prediction预测算法(附完整源码)
    查看>>
    Objective-C实现Luhn (Mod 10)Algorithm算法(附完整源码)
    查看>>
    Objective-C实现max subarray sum最大子数组和算法(附完整源码)
    查看>>
    Objective-C实现MaximumSubarray最大子阵列(动态规划解决方案)算法(附完整源码)
    查看>>
    Objective-C实现max_heap最大堆算法(附完整源码)
    查看>>
    Objective-C实现md5算法(附完整源码)
    查看>>
    Objective-C实现memoization优化技术算法(附完整源码)
    查看>>
    Objective-C实现memset函数功能(附完整源码)
    查看>>
    Objective-C实现merge insertion sort合并插入排序算法(附完整源码)
    查看>>
    Objective-C实现merge sort归并排序算法(附完整源码)
    查看>>
    Objective-C实现mergesort归并排序算法(附完整源码)
    查看>>