Spring Cloud Security 实现OAuth2.0 基础版demo

   最近在学习Spring Security 和 Spring Cloud Security ,这个模块还是比较复杂的,我一般学习的方法是先写一个demo,跑通然后在管细节。上一篇我们 我们也是研究了Spring Security (Spring Security 实现OAuth2.0实现授权服务--基础版 地址:https://blog.csdn.net/liuying1802028915/article/details/105082345 感兴趣的可以去看一下),上一篇由于一些原因没有获得token,这一片我们也是在借鉴了前人的基础上使用Spring Cloud Security 实现OAuth 然后获得token

借鉴的文章是:https://segmentfault.com/a/1190000019344734 感谢这篇作者

 

        先声明oauth2是一种协议规范,spring-security-oauth2是对他的一种实现。其次,还有shiro实现,自己根据规范编写代码的实现方式。主流的qq,微信等第三方授权登录方式都是基于oauth2实现的。
oauth2的认证方式有授权码,简单,账户密码,客户端等方式,具体请自行百度不做过多的阐述。 本文基于授权码方式实现
oauth生态设计的范围很大,可以说是一种解决方案,它有“第三方客户端(web服务,APP服务)”、“用户”、“认证服务器”、“资源服务器”等部分。认证流程如下图:

Spring Cloud Security 实现OAuth2.0 基础版demo_第1张图片

 

A)用户打开客户端以后,客户端要求用户给予授权。
(B)用户同意给予客户端授权。

(C)客户端使用上一步获得的授权,向认证服务器申请令牌。

(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。

(E)客户端使用令牌,向资源服务器申请获取资源。

(F)资源服务器确认令牌无误,同意向客户端开放资源。

接下来我们就来写代码,首先新建一个SpringBoot工程

Spring Cloud Security 实现OAuth2.0 基础版demo_第2张图片

 

Spring Cloud Security 实现OAuth2.0 基础版demo_第3张图片

父工程不引入任何依赖

Spring Cloud Security 实现OAuth2.0 基础版demo_第4张图片

创建过程不再赘述,创建完之后项目结构如下:

Spring Cloud Security 实现OAuth2.0 基础版demo_第5张图片

接下来 我们在父工程中配置依赖管理


        
            
                org.springframework.cloud
                spring-cloud-dependencies
                Greenwich.RC2
                pom
                import
            
            
                org.springframework.cloud
                spring-cloud-alibaba-dependencies
                0.9.0.RELEASE
                pom
                import
            
        
    

添加依赖管理后 父工程的pom文件如下:



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.2.5.RELEASE
         
    
    com.taoj.demo
    spring-cloud-oauth-demo07
    0.0.1-SNAPSHOT
    spring-cloud-oauth-demo07
    Demo project for Spring Boot

    
        1.8
    

    
        
            org.springframework.boot
            spring-boot-starter
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        
    

    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                Greenwich.RC2
                pom
                import
            
            
                org.springframework.cloud
                spring-cloud-alibaba-dependencies
                0.9.0.RELEASE
                pom
                import
            
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


接下来我们新建一个Module oauth-server

Spring Cloud Security 实现OAuth2.0 基础版demo_第6张图片

Spring Cloud Security 实现OAuth2.0 基础版demo_第7张图片

这里选择Cloud Oauth2 的依赖

Spring Cloud Security 实现OAuth2.0 基础版demo_第8张图片

Spring Cloud Security 实现OAuth2.0 基础版demo_第9张图片

接下来我们创建一个config包,因为,我们认证之前需要先校验用户的账户密码是否正确,所以我们先配置WebSecurityConfig拦截:

package com.taoj.deo.oauthserver.config;

import org.springframework.beans.factory.annotation.Autowired;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
//对全部方法进行验证
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    BCryptPasswordEncoder passwordEncoder;

    /**
     * 配置内存登陆用户认证
     * @param auth
     * @throws Exception
     */
    @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");
    }

}

在config方法里,我们在内存中,配置了两个用户,这里注意密码用了BCryptPasswordEncoder进行加密,在springboot2.x中不加密会报错的。
(4)到这里,用户验证已经完成,我们创建AuthConfig配置认证拦截处理:

package com.taoj.deo.oauthserver.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;

@Configuration
//开启认证服务
@EnableAuthorizationServer
public class AuthConfig extends AuthorizationServerConfigurerAdapter {

    /**
     * 配置密码加密 springboot2.x需要配置
     * @return
     */
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception{
        clients.inMemory()
                .withClient("client")
                .secret(passwordEncoder().encode("secret"))
                .authorizedGrantTypes("authorization_code")
                .scopes("app")
                .redirectUris("http://127.0.0.1:8080/say");
    }


}

需要添加 @EnableAuthorizationServer注解开启认证服务,注入加密用的BCryptPasswordEncoder实例。然后,配置需要认证的客户端,
这里需要细说一下,首先是client_id代表是哪个客户端也就是哪个APP或者web服务需要认证的,然后是客户端的secret秘钥需要加密,
authorizedGrantTypes授权方式指的是授权码,简单,客户端,账户密码等,这里使用的是授权码(authorization_code),然后是scopes范围,
redirectUris重定向地址,就是你的登录地址,授权后跳转的地址。

这里的redirectUris 我重定向到了一个 oauth-client项目中的Controller

oauth-client 项目结构的如下所示:

Spring Cloud Security 实现OAuth2.0 基础版demo_第10张图片

这个项目的端口是默认的8080

之后会附上源码

之后启动oauth-server

启动项目之后说无法访问 javax.servlet.Filter 

Spring Cloud Security 实现OAuth2.0 基础版demo_第11张图片

 

之后我在改子项目中添加对spring-boot-starter-web 的依赖之后


            org.springframework.boot
            spring-boot-starter-web
        

添加以来之后 重启 正常

之后在浏览器中访问 http://localhost:9000/oauth/authorize?client_id=client&response_type=code

访问之后进入登陆页面:

Spring Cloud Security 实现OAuth2.0 基础版demo_第12张图片

我们输入用户名密码:admin/123456

进入到这个页面:

Spring Cloud Security 实现OAuth2.0 基础版demo_第13张图片

我们选择approve点击Authorize认证

Spring Cloud Security 实现OAuth2.0 基础版demo_第14张图片

认证之后 

Spring Cloud Security 实现OAuth2.0 基础版demo_第15张图片

这个就是code
 

我们打开postman用post方式获取access_token

Spring Cloud Security 实现OAuth2.0 基础版demo_第16张图片

 

如果code写错会报错

Spring Cloud Security 实现OAuth2.0 基础版demo_第17张图片

这个client就是配置的client_id,secret就是配置的secret,返回access_token

至此基于内存的oauth2实现完成,我们也获取到了 token

你可能感兴趣的:(java学习)