Spring Security oauth2 介绍

介绍:什么是oAuth :oauth是一个协议,是为用户资源的授权提供一个安全的,开放而又简易的标准,与以往的授权方式不同之处是,oauth的授权不会使第三方接触到到第三方的账号信息,即第三方无需使用用户的用户名与密码就可以申请获得该用户的资源的授权,因此oauth 是安全的。

什么是Security:Spring Security 是一个安全框架,能够为Spring企业应用系统提供声明式的安全访问控制,Spring Security基于Servlet过滤器,Ioc和Aop,为Web请求和方法的调用提供身份确认和授权处理,避免了代码的耦合,减少了大量的重复代码。

交互过程:

 oauth 在客户端 与服务提供商之间,设置了一个授权层,客户端是不能直接登录 服务提供商的,只能登录授权层,从此将用户与客户端分来,客户端登录登录授权层所用的令牌(Token),与用户的密码不同,用户可以在登录的时候,指定授权层令牌的权限范围和有效期,客户端 登录授权层之后,服务提供商会根据令牌的权限范围和有效期,想客户端 开放用户存储的资料。

从上图我们可以看出,在交互模型涉及的共有三方

 资源拥有者:用户

 客户端:App、浏览器等。。

 服务提供方:

     认证服务器

     资源服务器

 什么是认证服务器:

    认证服务器负责对用户进行认证,并授权给客户端权限,认证很容易(验证账户和密码即可),问题在于如何授权,比如当我们使用第三方登陆时,比如qq,会直接跳转到qq的登录页面,同时会有 授权 的字样 

认证服务器在认证的时候,需要知道 请求授权 的客户端的身份以及该客户端的请求的权限,我们可以为每一个客户端预先分配一个id,并给每个id对应一个名称以及权限的信息,这些信息可以写在认证服务器上的配置文件中,然后,客户端每次打开授权页面的时候,把属于自己的id传递过来,如下:

http://localhost:8080/login?client_id=yourClientId

但是随着时间的推移和业务的增长,会发现,修改配置的工作消耗太多的人力。

oAuth2开放平台

开放平台是由oAuth2.0 协议衍生出的一个产品,他的作用就是让客户端自己去这面去注册、申请、通过之后系统自动分配client_id ,并完成配置的自动更新(通常是写进数据库)。客户端要完成申请,通常需要填写客户端程序的类型(Web。app等)、企业介绍,执照,想要获取的权限等信息,这些信息在得到服务提供方的人工审核通过之后,开放平台会自动分配一个client_id给客户端。

到这里就实现登录认证,授权页的信息展示,那么接下来,当用户进行授权之后,认证服务器需要把产生的access_token 发送给客户端,方案如下;

 让客户端开放平台申请的时候,填写一个URL,例如:http://localhost:8080/

  每次当用户授权成功之后,认证服务器将页面重定向到 这个URL(回调),并带上access_token,例如:http://localhost:8080?access_token=123123

  客户端接受到了这个 access_token 而且认证服务器的授权动作已经完成,刚好把程序的控制权交给客户端,由客户端决定接下来向用户展示什么内容。

下面讲解什么时候 Access Token :

  Access Token 是客户端访问资源服务器的令牌,拥有这个令牌代表得到用户的授权,然而这个令牌是临时的,有一定的有效期,这是因为 Access Token 在使用过程会可能泄露,给Access token 限定一个较短的 有效期,可以降低因Access Token 泄露带来的风险。

  但是在这样引入有效期之后,客户端使用起来就不方便,每当Access Token 过期,客户端就必须重新向用户索要授权,于是oAuth2.0引入了 Refresh token 的机制

Refresh Token

   Refresh Token 的作用是用用来刷新Access token 的,认证服务器提供一个刷新的接口,

http://localhost:8080/refresh?refresh_token=&client_id=

传入 refresh_token 和 client_id ,认证服务器验证通过之后,返回一个新的Access Token 为了安全,oAuth2引入了两个措施:

    oAuth2.0 要求,Refresh Token 一定 保存在客户端的服务器上, 而觉不能存放在客户端(app 、pc端软件)上,调用refresh 接口的时候,一定是从 服务器到服务器的访问。

    oauth2.0 引入了 client_secret 机制,即每一个 clieng_id 都对应一个clieng_secret ,这个clieng_secret 机制,即每一个clieng_id 都对应一个clieng_secret 一起分配给客户端,客户端 必须把 clieng_secret 妥善保存在服务器上,决不能泄露,在刷新Access Token时,需要验证这个client_secret.

http://localhost:8080/refresh?refresh_token=&client_id=&client_secret=

这就是 Refresh Token 的机制,Refresh Token 的有效期非常长,会在用户授权时,随Access Token 一起重定向到回调URL 传递给客户端

 

下面讲解什么是授权模式:

    客户端在必须得到用户的授权(authorization grant),才能获取到令牌(access token)。oAuth2定义了四种授权方式

  implicit : 简化模式,不推荐使用

  authorization code : 授权码模式

  resource owner password credentials : 密码模式

  client credentals : 客户端模式

  简化模式:

   简化模式适合用于纯静态页面的应用,所谓纯静态页面的应用,也就是应用没有在服务器上执行代码的权限(通常就是吧代码托管到别人服务器上),只有前端js 代码的控制权,相当于只有h5 客户端,没有后台,使用该模式,该模式中的Access Token 容易泄露,且不可刷新

授权码模式:

   授权码模式适用于自己的服务器i的应用,他是一个一次性的临时凭证,用来换取access_token 和 refresh_token 认证服务器提供了一个类似这样的接口,。

https://localhost:8080/exchange?code=&client_id=&client_secret=

 需要传入 code 、client_id 以及 client_secret 验证通过之后,返回Access_token 和 refresh_token ,一旦换取成功,code 立即作废,不能在使用第二次。

  

这个code 的作用是保护Token 的安全性,简单模式不安全的原因是,在第四步重定向将token返回给应用的时候,这一步容易v被拦截,但是在引入code 之后,即使获取到code,但是由于无法获取保存在服务器的client_secret ,因为也无法通过code 换取token,在第五步,是服务器与服务器之间的访问,所以不容易拦截,其次,这个请求通常是https的实现,即使能监听到数据包也无法解析出内容。

使用场景: 不对外提供账户和密码,自己使用账户和密码

所以说有了这个code,token的安全性大大的提高,因此,oAuth2.0 鼓励使用这种方式进行授权。

密码模式:

  在密码模式中,用户向客户端提供自己的用户名和密码,客户端使用这些信息,想 服务商提供商所要授权,在这种模式下,用户必须把自己的密码给客户端,但是客户端不存储密码,这通常用在对客户端高度信任的情况下,比如客户端是操作系统的一部分。

该模式的使用场景:一个公司的两个系统,登录一个系统的时候同时登录另外一个系统

在使用的时候,第2步中,认证服务器需要对客户端的身份进行验证,确保是受信任的客户端

客户端模式:

  两个客户端公用一个后端的模块,没有用户界面的时候,可以用户客户端模式

下面的代码是一个简单的小案例,可以对Tocken 的刷新,获取,然后访问静态资源数据,但是这些并没有真正的与qq等第三方对接,后续的代码还在更新中....

首选查看我的项目的结构:

首先是spring-security-oauth2 的 pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.funtl</groupId>
    <artifactId>spring-security-oathou2</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <url>http://www.funtl.com</url>

    <modules>
        <module>spring-security-oauth2-dependencies</module>
        <module>spring-security-oauth2-server</module>
        <module>spring-security-oauth2-resource</module>
    </modules>

    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <licenses>
        <license>
            <name>Apache 2.0</name>
            <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
        </license>
    </licenses>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.funtl</groupId>
                <artifactId>spring-security-oauth2-dependencies</artifactId>
                <version>${project.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <profiles>
        <profile>
            <id>default</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <spring-javaformat.version>0.0.7</spring-javaformat.version>
            </properties>
            <build>
                <plugins>
                    <plugin>
                        <groupId>io.spring.javaformat</groupId>
                        <artifactId>spring-javaformat-maven-plugin</artifactId>
                        <version>${spring-javaformat.version}</version>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <configuration>
                            <includes>
                                <include>**/*Tests.java</include>
                            </includes>
                            <excludes>
                                <exclude>**/Abstract*.java</exclude>
                            </excludes>
                            <systemPropertyVariables>
                                <java.security.egd>file:/dev/./urandom</java.security.egd>
                                <java.awt.headless>true</java.awt.headless>
                            </systemPropertyVariables>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-enforcer-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>enforce-rules</id>
                                <goals>
                                    <goal>enforce</goal>
                                </goals>
                                <configuration>
                                    <rules>
                                        <bannedDependencies>
                                            <excludes>
                                                <exclude>commons-logging:*:*</exclude>
                                            </excludes>
                                            <searchTransitive>true</searchTransitive>
                                        </bannedDependencies>
                                    </rules>
                                    <fail>true</fail>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-install-plugin</artifactId>
                        <configuration>
                            <skip>true</skip>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-javadoc-plugin</artifactId>
                        <configuration>
                            <skip>true</skip>
                        </configuration>
                        <inherited>true</inherited>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

    <repositories>
        <repository>
            <id>spring-milestone</id>
            <name>Spring Milestone</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshot</id>
            <name>Spring Snapshot</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestone</id>
            <name>Spring Milestone</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-snapshot</id>
            <name>Spring Snapshot</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>

总的一个依赖的管理是 spring-security-oauth2-dependencies 项目

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.funtl</groupId>
    <artifactId>spring-security-oauth2-dependencies</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <url>http://www.funtl.com</url>

    <properties>
        <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
        <spring-boot-mapper.version>2.1.5</spring-boot-mapper.version>
    </properties>

    <licenses>
        <license>
            <name>Apache 2.0</name>
            <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
        </license>
    </licenses>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.zaxxer</groupId>
                <artifactId>HikariCP</artifactId>
                <version>${hikaricp.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
                <exclusions>
                    <!-- 排除 tomcat-jdbc 以使用 HikariCP -->
                    <exclusion>
                        <groupId>org.apache.tomcat</groupId>
                        <artifactId>tomcat-jdbc</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>tk.mybatis</groupId>
                <artifactId>mapper-spring-boot-starter</artifactId>
                <version>${spring-boot-mapper.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <repositories>
        <repository>
            <id>spring-milestone</id>
            <name>Spring Milestone</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshot</id>
            <name>Spring Snapshot</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestone</id>
            <name>Spring Milestone</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-snapshot</id>
            <name>Spring Snapshot</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

</project>

注意当spring boot 在使用 2.1之后以后,spring cloud 是用G 开头的,如果是2.0的需要使用F开头的,要不然会出错

spring-security-oauth2-server 是oauth2 的认证和授权的服务

查看pom 文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.funtl</groupId>
        <artifactId>spring-security-oathou2</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>spring-security-oauth2-server</artifactId>

    <licenses>
        <license>
            <name>Apache 2.0</name>
            <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
        </license>
    </licenses>


    <dependencies>
        <!-- Spring Boot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <!-- Spring Security -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>

        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <exclusions>
                <!-- 排除 tomcat-jdbc 以使用 HikariCP -->
                <exclusion>
                    <groupId>org.apache.tomcat</groupId>
                    <artifactId>tomcat-jdbc</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
        </dependency>
        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.funtl.springsecurityoauth2server.SpringSecurityOauth2ServerApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

这是所需要到的pom的依赖

我们首选查看 Spring security的配置

package com.funtl.springsecurityoauth2server.server.config;

import com.funtl.springsecurityoauth2server.server.config.service.UserDetailsServiceImpl;
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;

/**
 * R认证账号是否有效
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {


    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


    /** 该返回的类,在spring 中是存在的,所以需要重写,换成自己的
     * @return
     */
    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        return new UserDetailsServiceImpl();
    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 基于内存的认证
//        auth
//                .inMemoryAuthentication()
//                .withUser("admin")
//                .password(passwordEncoder().encode("123456"))
//                .roles("ADMIN")
//                .and()
//                .withUser("user")
//                .password(passwordEncoder().encode("123456"))
//                .roles("USER");
        // 基于数据库的认证
        auth.userDetailsService(userDetailsService());
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // 将指定端口,暴露出去,因为在请求认证的时候,需要去访问一个    check_token 的一个端口,
        // 如果不将 check_token 暴露出去,会出现403的错误
        web.ignoring().antMatchers("/oauth/check_token");
    }
}

上面的代码我们可以看到,Spring boot  Security 提供了一个类。 WebSecurityConfigurerAdapter 该类是一个抽象的接口,

configure(AuthenticationManagerBuilder auth) : 该类是对用户的认证

package com.funtl.springsecurityoauth2server.server.config.service;

import com.funtl.springsecurityoauth2server.server.domain.TbPermission;
import com.funtl.springsecurityoauth2server.server.domain.TbUser;
import com.funtl.springsecurityoauth2server.server.service.TbPermissionService;
import com.funtl.springsecurityoauth2server.server.service.TbUserService;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 完成用户的认证与授权的工作,将用户的信息和角色信息,全部交给 框架去管理
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {


    @Autowired
    private TbUserService tbUserService;

    @Autowired
    private TbPermissionService tbPermissionService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 查询用户的信息
        TbUser byUsername = tbUserService.getByUsername(username);
        List<GrantedAuthority> grantedAuthorityArrayList = Lists.newArrayList();
        //
        if (byUsername != null) {
            // 进行授权  查看是否有权限
            List<TbPermission> tbPermissions =
                    tbPermissionService.selectByUserId(byUsername.getId());
            if(tbPermissions.size() >0){
                tbPermissions.forEach(tbPermission -> {
                    if (tbPermission != null && tbPermission.getEnname() != null) {
                        GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(tbPermission.getEnname());
                        grantedAuthorityArrayList.add(grantedAuthority);
                    }
                });
            }
        }
        return new User(byUsername.getUsername(), byUsername.getPassword(), grantedAuthorityArrayList);
    }
}

  将用于的信息,权限,交给框架去管理。

上面的步骤是进行认证,下面开始授权的操作。

package com.funtl.springsecurityoauth2server.server.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;

import javax.sql.DataSource;

/**
 * 授权
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {


    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    // 创建数据源

    /** 存储 返回的 Tokin 数据
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore());
    }


    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource(){
        return DataSourceBuilder.create().build();
    }

    @Bean
    public TokenStore tokenStore() {
        return new JdbcTokenStore(dataSource());
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        /*// 使用客户端模式   需要知道那个客户端 来进行请求
        clients.
                // 使用本地内存存储
                        inMemory().
                // 发送的 clientId
                        withClient("client").
                // client_secret
                        secret(passwordEncoder.encode("secret")).
                // 授权的类型
                        authorizedGrantTypes("authorization_code")
                // 授权的范围
                .scopes("app")
                // 回调的地址
                .redirectUris("http://localhost:8080/oauth2-server/controller/hello");*/

        //  使用jdbc 的方式,将数据库中的数据进行获取
        clients.withClientDetails(jdbcClientDetails());
    }

    @Bean
    public ClientDetailsService jdbcClientDetails() {
        return  new JdbcClientDetailsService(dataSource());
    }


}

Sql

CREATE TABLE `tb_permission` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `parent_id` bigint(20) DEFAULT NULL COMMENT '父权限',
  `name` varchar(64) NOT NULL COMMENT '权限名称',
  `enname` varchar(64) NOT NULL COMMENT '权限英文名称',
  `url` varchar(255) NOT NULL COMMENT '授权路径',
  `description` varchar(200) DEFAULT NULL COMMENT '备注',
  `created` datetime NOT NULL,
  `updated` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8 COMMENT='权限表';
insert  into `tb_permission`(`id`,`parent_id`,`name`,`enname`,`url`,`description`,`created`,`updated`) values 
(37,0,'系统管理','System','/',NULL,'2019-04-04 23:22:54','2019-04-04 23:22:56'),
(38,37,'用户管理','SystemUser','/users/',NULL,'2019-04-04 23:25:31','2019-04-04 23:25:33'),
(39,38,'查看用户','SystemUserView','/users/view/**',NULL,'2019-04-04 15:30:30','2019-04-04 15:30:43'),
(40,38,'新增用户','SystemUserInsert','/users/insert/**',NULL,'2019-04-04 15:30:31','2019-04-04 15:30:44'),
(41,38,'编辑用户','SystemUserUpdate','/users/update/**',NULL,'2019-04-04 15:30:32','2019-04-04 15:30:45'),
(42,38,'删除用户','SystemUserDelete','/users/delete/**',NULL,'2019-04-04 15:30:48','2019-04-04 15:30:45'),
(44,37,'内容管理','SystemContent','/contents/',NULL,'2019-04-06 18:23:58','2019-04-06 18:24:00'),
(45,44,'查看内容','SystemContentView','/contents/view/**',NULL,'2019-04-06 23:49:39','2019-04-06 23:49:41'),
(46,44,'新增内容','SystemContentInsert','/contents/insert/**',NULL,'2019-04-06 23:51:00','2019-04-06 23:51:02'),
(47,44,'编辑内容','SystemContentUpdate','/contents/update/**',NULL,'2019-04-06 23:51:04','2019-04-06 23:51:06'),
(48,44,'删除内容','SystemContentDelete','/contents/delete/**',NULL,'2019-04-06 23:51:08','2019-04-06 23:51:10');

CREATE TABLE `tb_role` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `parent_id` bigint(20) DEFAULT NULL COMMENT '父角色',
  `name` varchar(64) NOT NULL COMMENT '角色名称',
  `enname` varchar(64) NOT NULL COMMENT '角色英文名称',
  `description` varchar(200) DEFAULT NULL COMMENT '备注',
  `created` datetime NOT NULL,
  `updated` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COMMENT='角色表';
insert  into `tb_role`(`id`,`parent_id`,`name`,`enname`,`description`,`created`,`updated`) values 
(37,0,'超级管理员','admin',NULL,'2019-04-04 23:22:03','2019-04-04 23:22:05');

CREATE TABLE `tb_role_permission` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `role_id` bigint(20) NOT NULL COMMENT '角色 ID',
  `permission_id` bigint(20) NOT NULL COMMENT '权限 ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=48 DEFAULT CHARSET=utf8 COMMENT='角色权限表';
insert  into `tb_role_permission`(`id`,`role_id`,`permission_id`) values 
(37,37,37),
(38,37,38),
(39,37,39),
(40,37,40),
(41,37,41),
(42,37,42),
(43,37,44),
(44,37,45),
(45,37,46),
(46,37,47),
(47,37,48);

CREATE TABLE `tb_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `password` varchar(64) NOT NULL COMMENT '密码,加密存储',
  `phone` varchar(20) DEFAULT NULL COMMENT '注册手机号',
  `email` varchar(50) DEFAULT NULL COMMENT '注册邮箱',
  `created` datetime NOT NULL,
  `updated` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`) USING BTREE,
  UNIQUE KEY `phone` (`phone`) USING BTREE,
  UNIQUE KEY `email` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COMMENT='用户表';
insert  into `tb_user`(`id`,`username`,`password`,`phone`,`email`,`created`,`updated`) values 
(37,'admin','$2a$10$9ZhDOBp.sRKat4l14ygu/.LscxrMUcDAfeVOEPiYwbcRkoB09gCmi','15888888888','lee.lusifer@gmail.com','2019-04-04 23:21:27','2019-04-04 23:21:29');

CREATE TABLE `tb_user_role` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) NOT NULL COMMENT '用户 ID',
  `role_id` bigint(20) NOT NULL COMMENT '角色 ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COMMENT='用户角色表';
insert  into `tb_user_role`(`id`,`user_id`,`role_id`) values 
(37,37,37);

下面直讲解对于请求的拦截

package com.funtl.springsecurityoauth2resource.config;

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.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 {
        http.
                exceptionHandling()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/")
                .hasAnyAuthority("SystemContent")
                .antMatchers("/view/**").hasAuthority("SystemContentView")
                .antMatchers("/insert/**").hasAuthority("SystemContentInsert")
                .antMatchers("/update/**").hasAuthority("SystemContentUpdate")
                .antMatchers("/delete/**").hasAuthority("SystemContentDelete");
    }
}

具体的大概的操作如上,因为没有具体的页面,所以我就不详细说了,代码我没有上传,需要的留言。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值