springboot快速搭建oauth2 内存版身份认证

OAuth 2.0是用于授权的行业标准协议。OAuth 2.0取代了在2006年创建的原始OAuth协议上所做的工作。OAuth 2.0专注于客户端开发人员的简单性,同时为Web应用程序,桌面应用程序,手机和客厅设备提供特定的授权流程。

开发工具:Idea

开发环境:jdk1.8 、maven3.5.0

springboot 2.1.3

1、点击【Create New Project】创建一个新的项目

选择【Spring Initializr】选择JDK1.8,然后点击Next

接下来填好对应的资料,点击Next:

然后选择Springboot2.1.3,然后勾选:

接下来点击Next

点击Finish开始项目的编写

我们开始一个项目的时候,首先要一步一步的去配置,不能一下盲目的去配置一大堆东西后去运行,这样如果出错了就很难排错,我们一步步去配置所要的框架然后去运行没问题了再去配置下一个。

我们先是安装Thymeleaf

加入依赖:

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-thymeleaf</artifactId>

</dependency>

然后去resources目录下面新建配置文件:application.yml

然后开始配置thymeleaf:

server:

  port: 8888

#thymeleaf

spring:

  thymeleaf:

    prefix: classpath:/templates/

    suffix: .html

    cache: false

    encoding: UTF-8

    mode: LEAGCYHTML5

    servlet:

      content-type: text/html

然后我们再去创建Controller包和ApiController.class类去编写跳转

package com.oauth2.pan.controller;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.servlet.ModelAndView;

/**

* @Author: Caiden(张志鑫)

* @Date: 2019/2/26 15:18

* @Version 0.0.1

*/

@Controller

@RequestMapping("/api")

public class ApiController {

    @RequestMapping("/hello")

    public ModelAndView sayHelloWorld(ModelAndView model){

        model.setViewName("index");

        return model;

    }

}

然后在resources -> templates 目录下新建一个html文件:index.html。启动运行测试:

可以访问,说明我们thymeleaf框架搭建好了。

此刻我们的目录结构:

接下来搭建我们的oauth2认证,我们加入两个依赖包

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-security</artifactId>

</dependency>

<dependency>

    <groupId>org.springframework.security.oauth</groupId>

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

    <version>2.1.3.RELEASE</version>

</dependency>

需要注意的问题一:

1、当我们加入依赖包后可以在项目的External Libraries看下jar包是不是已经被加入到项目里面,有些时候Jar已经通过Maven下载完成,但是没有导入进来。

2、打开File->Project Structure -》Project Settings -> Libraries 中看oauth2的jar包是否有加载进来,如果下图中绿色框框中是红色,请确保MAVEN下载JAR包成功的情况下,删除classes中的信息,再点击绿色框上边最左边的“+”号,选择MAVEN下载好的jar包即可

当上面提到的两个依赖jar包确认下载并加载成功后,开始进行认证编码:

WebSecurityConfigurerAdapter是默认情况下Spring security的http配置;ResourceServerConfigurerAdapter是默认情况下spring security oauth 的http配置。

(WebSecurityConfigurerAdapter的配置拦截要优先于ResourceServerConfigurerAdapter,优先级高的http配置是可以覆盖优先级低的配置的)

先覆写spring Security的http配置

新建类名:WebSecurityConfiguration 然后去继承 WebSecurityConfigurerAdapter

老司机避坑指南:解决 There is no PasswordEncoder mapped for the id "null")

SpringBoot升级到了2.0之后的版本,Security也由原来的版本4升级到了5

升到5版本之后的security必须加入密码加密

WebSecurityConfiguration.class

package com.oauth2.pan.config;

import org.springframework.context.annotation.Bean;

import org.springframework.security.authentication.AuthenticationManager;

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.HttpSecurity;

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;

import org.springframework.security.crypto.password.PasswordEncoder;

/**

* @Author: Caiden(张志鑫)

* @Date: 2019/2/26 15:57

* @Version 0.0.1

*/

@EnableGlobalMethodSecurity(prePostEnabled = true)

@EnableWebSecurity

public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override

    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable();

        http.requestMatchers().antMatchers("/oauth/**","/login/**","/logout/**")

                .and()

                .authorizeRequests()

                .antMatchers("/oauth/**").authenticated()

                .and()

                .formLogin().permitAll();

    }

    @Override

    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

        auth.inMemoryAuthentication().passwordEncoder(encoder)

                .withUser("admin")

                .password(encoder.encode("admin1234")).roles("USER");

    }

    /**

    * 需要配置这个支持password模式

    */

    @Override

    @Bean

    public AuthenticationManager authenticationManagerBean() throws Exception {

        return super.authenticationManagerBean();

    }

    /**

    * 密码加密

    * */

    @Bean

    public PasswordEncoder passwordEncoder() {

        return new BCryptPasswordEncoder();

    }

}

再去覆写Oauth2的http配置类

ResourceServerConfig.class

package com.oauth2.pan.config.oauth2;

import org.springframework.context.annotation.Configuration;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;

import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;

import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;

import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;

/**

* @Author: Caiden(张志鑫)

* @Date: 2019/2/26 16:07

* @Version 0.0.1

*/

@Configuration

@EnableResourceServer

public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    private static final String PAN_RESOURCE_ID = "*";

    @Override

    public void configure(HttpSecurity http) throws Exception {

        http.requestMatchers().antMatchers("/api/**")

                .and()

                .authorizeRequests()

                .antMatchers("/api/**").authenticated();

    }

    @Override

    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {

        resources.resourceId(PAN_RESOURCE_ID);

    }

}

再去新建一个认证服务器:

AuthorizationServerConfiguration.class

package com.oauth2.pan.config.oauth2;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.security.authentication.AuthenticationManager;

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.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;

import org.springframework.security.oauth2.provider.token.TokenStore;

import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

/**

* @Author: Caiden(张志鑫)

* @Date: 2019/2/26 16:10

* @Version 0.0.1

*/

@Configuration

@EnableAuthorizationServer

public class AuthorizationServerConfiguration  extends AuthorizationServerConfigurerAdapter {

    @Autowired

    private TokenStore tokenStore;

    @Autowired

    private AuthenticationManager authenticationManager;

    @Override

    public void configure(AuthorizationServerSecurityConfigurer security)throws Exception {

        security.allowFormAuthenticationForClients();

    }

    @Override

    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

        //添加客户端信息

        //使用内存存储OAuth客户端信息

        clients.inMemory()

                // client_id

                .withClient("test")

                // 该client允许的授权类型,不同的类型,则获得token的方式不一样。

                .authorizedGrantTypes("password")

                // client_secret

                .secret(encoder.encode("123456"))

                .resourceIds("*")

                // 允许的授权范围

                .scopes("all")

                .accessTokenValiditySeconds(1000) //token过期时间

                .refreshTokenValiditySeconds(1000); //refresh过期时间;

    }

    @Override

    public void configure(AuthorizationServerEndpointsConfigurer endpoints)throws Exception {

        //reuseRefreshTokens设置为false时,每次通过refresh_token获得access_token时,也会刷新refresh_token;也就是说,会返回全新的access_token与refresh_token。

        //默认值是true,只返回新的access_token,refresh_token不变。

        endpoints.tokenStore(tokenStore)

                .authenticationManager(authenticationManager);

    }

    @Bean

    public TokenStore tokenStore() {

        //token保存在内存中(也可以保存在数据库、Redis中)。

        //如果保存在中间件(数据库、Redis),那么资源服务器与认证服务器可以不在同一个工程中。

        //注意:如果不保存access_token,则没法通过access_token取得用户信息

        return new InMemoryTokenStore();

    }

}

好了,都配置好了,万事OK,快去测试一下吧。

关于分享有何疑问与建议欢迎留言哦!

如果你对Spring有兴趣,实训邦精心准备了Spring2.0的深度技术讲解。

可以通过链接学习更多SpringBoot+Vue前后端分离的内容。

https://ke.qq.com/course/447591?flowToken=1013796

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容