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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容