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

本文共 7841 字,大约阅读时间需要 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@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()");    }}

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/

    你可能感兴趣的文章
    mysql8 配置文件配置group 问题 sql语句group不能使用报错解决 mysql8.X版本的my.cnf配置文件 my.cnf文件 能够使用的my.cnf配置文件
    查看>>
    MySQL8.0.29启动报错Different lower_case_table_names settings for server (‘0‘) and data dictionary (‘1‘)
    查看>>
    MYSQL8.0以上忘记root密码
    查看>>
    Mysql8.0以上重置初始密码的方法
    查看>>
    mysql8.0新特性-自增变量的持久化
    查看>>
    Mysql8.0注意url变更写法
    查看>>
    Mysql8.0的特性
    查看>>
    MySQL8修改密码报错ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
    查看>>
    MySQL8修改密码的方法
    查看>>
    Mysql8在Centos上安装后忘记root密码如何重新设置
    查看>>
    Mysql8在Windows上离线安装时忘记root密码
    查看>>
    MySQL8找不到my.ini配置文件以及报sql_mode=only_full_group_by解决方案
    查看>>
    mysql8的安装与卸载
    查看>>
    MySQL8,体验不一样的安装方式!
    查看>>
    MySQL: Host '127.0.0.1' is not allowed to connect to this MySQL server
    查看>>
    Mysql: 对换(替换)两条记录的同一个字段值
    查看>>
    mysql:Can‘t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock‘解决方法
    查看>>
    MYSQL:基础——3N范式的表结构设计
    查看>>
    MYSQL:基础——触发器
    查看>>
    Mysql:连接报错“closing inbound before receiving peer‘s close_notify”
    查看>>