【Spring-Security】Re10 Oauth2协议 P1 授权码模式 & 密码模式
一、Oauth2协议:
第三方登录,即忘记本站密码,但是登录界面中提供了一些第三方登录,例如微信、支付宝、QQ、等等,通过第三方授权实现登录
第三方认证技术主要解决的时认证标准,各个平台的登录要遵循统一的接口协议
所以这里采用的方案是Oauth2
资料参考:
https://www.jianshu.com/p/84a4b4a1e833
二、Spring-Security + Oauth2 环境搭建
创建一个空的SpringBoot项目:
删除不必要的文件

导入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 https://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.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.zeal4j</groupId>
<artifactId>so2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>so2</name>
<description>Spring-Security + Oauth2 project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties> <dependencies> <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
<!--<version>2.2.4.RELEASE</version>-->
</dependency> <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
<!--<version>2.2.4.RELEASE</version>-->
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version><!--<version>Greenwich.SR2</version>-->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>
用户实体类:
package cn.zeal4j.domain; import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import java.util.Collection; /**
* @author Administrator
* @file Spring-Security + Oauth2
* @create 2020 09 29 11:37
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements UserDetails {
private String username;
private String password;
private Collection<GrantedAuthority> authorities; @Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
} @Override
public String getPassword() {
return null;
} @Override
public String getUsername() {
return null;
} @Override
public boolean isAccountNonExpired() {
return false;
} @Override
public boolean isAccountNonLocked() {
return false;
} @Override
public boolean isCredentialsNonExpired() {
return false;
} @Override
public boolean isEnabled() {
return false;
}
}
Security安全配置:
package cn.zeal4j.configuration; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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 Administrator
* @file Spring-Security + Oauth2
* @create 2020 09 29 11:35
*/
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
} @Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
// csrf
httpSecurity.csrf().disable(); // 登录,退出,授权放行
httpSecurity.authorizeRequests().antMatchers("/login/**","/logout/**","/oauth/**/").permitAll(); // 允许表单登录
httpSecurity.formLogin().permitAll(); // 其余请求权限拦截
httpSecurity.authorizeRequests().anyRequest().authenticated();
}
}
授权服务配置:
package cn.zeal4j.configuration; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.password.PasswordEncoder;
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; /**
* @author Administrator
* @file Spring-Security + Oauth2
* @create 2020 09 29 11:48
* @description 授权服务器配置
*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { @Autowired
private PasswordEncoder passwordEncoder; @Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.
inMemory().
withClient("admin").
secret(passwordEncoder.encode("112233")).
accessTokenValiditySeconds(3600). // 令牌有效时间 一小时
redirectUris("http://www.baidu.com"). // 授权成功的跳转
scopes("all"). // 所有范围
authorizedGrantTypes("authorization_code"); // 授权类型:授权码模式
}
}
资源服务配置:
package cn.zeal4j.configuration;
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; /**
* @author Administrator
* @file Spring-Security + Oauth2
* @create 2020 09 29 11:57
*/ @Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { @Override
public void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity.authorizeRequests().
anyRequest().authenticated(). // 默认任何请求都需要授权
and().
requestMatchers().antMatchers("/user/**"); // 资源匹配规则
}
}
登录逻辑:
package cn.zeal4j.service.impl; import cn.zeal4j.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder; /**
* @author Administrator
* @file Spring-Security + Oauth2
* @create 2020 09 29 11:35
*/
@Service
public class CustomUserDetailsServiceImpl implements UserDetailsService { @Autowired
private PasswordEncoder passwordEncoder; @Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
String encode = passwordEncoder.encode("123456");
return new User("admin", encode, AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
}
}
User资源控制器:
package cn.zeal4j.controller; import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; /**
* @author Administrator
* @file Spring-Security + Oauth2
* @create 2020 09 29 12:01
*/
@Controller
@RequestMapping("user")
public class UserController { /**
* 获取当前用户
* @param authentication
* @return user/getCurrentUser
*/
@RequestMapping("/getCurrentUser")
@ResponseBody
public Object getCurrentUser(Authentication authentication) {
return authentication.getPrincipal();
} }
启动访问发现:

二、授权码模式实现:
发现生成的UserDetails实例默认设置的都是False,SpringSecurity一经权限判断,直接触发拦截
所以默认这里都要改成TRUE放行通过
@Override
public String getPassword() {
return password;
} @Override
public String getUsername() {
return username;
} @Override
public boolean isAccountNonExpired() {
return true;
} @Override
public boolean isAccountNonLocked() {
return true;
} @Override
public boolean isCredentialsNonExpired() {
return true;
} @Override
public boolean isEnabled() {
return true;
}
再次测试Oauth2地址:
http://localhost:8080/oauth/authorize?response_type=code&client_id=admin&redirect_uri=http://www.baidu.com&scope=all

点击选择Approve允许,点击Authorize进行授权

https://www.baidu.com/?code=G6ocWn
这个code就是我们的授权码
现在使用Postman进行测试:
1、先选择认证账号信息输入:

2、然后输入请求参数:

grant_type authorization_code
code 你得到的授权码
cient_id admin
redirect_uri http://www.baidu.com
scope all
请求成功则会返回这个消息JSON
{
"access_token": "4c562cc7-07c4-47b6-9a5b-537c4f4079cd",
"token_type": "bearer",
"expires_in": 43199,
"scope": "all"
}
得到了许可Token
接着用Token访问资源获取接口:
http://localhost:8080/user/getCurrentUser

得到我们返回的数据:
{
"username": "admin",
"password": "$2a$10$tBlHK4KbNFsE7F7usl6AsODWWBkF4oS8Ak4qkaNbEFAsKykvXgH9i",
"authorities": [
{
"authority": "admin"
}
],
"enabled": true,
"accountNonLocked": true,
"credentialsNonExpired": true,
"accountNonExpired": true
}
如果令牌是错误的
{
"error": "invalid_token",
"error_description": "Invalid access token: 2287c3ab-3dc5-475e-97eb-bdffb2a78b8A"
}
三、密码模式授权实现:
package cn.zeal4j.configuration; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
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; /**
* @author Administrator
* @file Spring-Security + Oauth2
* @create 2020 09 29 11:48
* @description 授权服务器配置
*/
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { @Autowired
private PasswordEncoder passwordEncoder; @Autowired
private AuthenticationManager authenticationManager;
@Qualifier("customUserDetailsServiceImpl")
@Autowired
private UserDetailsService userDetailsService; /**
* 使用密码模式需要的配置方法
* @param endpoints
* @throws Exception
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.
authenticationManager(authenticationManager).
userDetailsService(userDetailsService);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.
inMemory().
withClient("admin").
secret(passwordEncoder.encode("112233")).
// accessTokenValiditySeconds(3600). // 令牌有效时间 一小时
redirectUris("http://www.baidu.com"). // 授权成功的跳转
scopes("all"). // 所有范围
// authorizedGrantTypes("authorization_code"); // 授权类型:授权码模式
authorizedGrantTypes("password"); // 授权类型:密码模式
}
}
授权管理器Bean的注入:
package cn.zeal4j.configuration; import org.omg.CORBA.PUBLIC_MEMBER;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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 Administrator
* @file Spring-Security + Oauth2
* @create 2020 09 29 11:35
*/
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
} @Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
} @Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.
csrf().
disable().
authorizeRequests().
antMatchers("/login/**","/logout/**","/oauth/**/").permitAll().
anyRequest().authenticated().
and().
formLogin().permitAll(); // // csrf
// httpSecurity.csrf().disable();
//
// // 登录,退出,授权放行
// httpSecurity.authorizeRequests().antMatchers("/login/**","/logout/**","/oauth/**/").permitAll();
//
// // 允许表单登录
// httpSecurity.formLogin().permitAll();
//
// // 其余请求权限拦截
// httpSecurity.authorizeRequests().anyRequest().authenticated();
}
}
Postman请求的地址和前面的密码不变,但是更改授权参数

{
"access_token": "8e51bdc3-50cd-42bd-b41c-28f06e5eca1f",
"token_type": "bearer",
"expires_in": 43199,
"scope": "all"
}
用密码模式的令牌获取用户主体,也能拿到用户主体的信息:

【Spring-Security】Re10 Oauth2协议 P1 授权码模式 & 密码模式的更多相关文章
- Spring Security实现OAuth2.0授权服务 - 基础版
一.OAuth2.0协议 1.OAuth2.0概述 OAuth2.0是一个关于授权的开放网络协议. 该协议在第三方应用与服务提供平台之间设置了一个授权层.第三方应用需要服务资源时,并不是直接使用用户帐 ...
- Spring Cloud2.0之Oauth2环境搭建(授权码模式和密码授权模式)
oauth2 server 微服务授权中心, github源码 https://github.com/spring-cloud/spring-cloud-security 对微服务接口做一些权 ...
- Spring Security实现OAuth2.0授权服务 - 进阶版
<Spring Security实现OAuth2.0授权服务 - 基础版>介绍了如何使用Spring Security实现OAuth2.0授权和资源保护,但是使用的都是Spring Sec ...
- Spring Security中实现微信网页授权
微信公众号提供了微信支付.微信优惠券.微信H5红包.微信红包封面等等促销工具来帮助我们的应用拉新保活.但是这些福利要想正确地发放到用户的手里就必须拿到用户特定的(微信应用)微信标识openid甚至是用 ...
- Spring Security 与 OAuth2 介绍
个人 OAuth2 全部文章 Spring Security 与 OAuth2(介绍):https://www.jianshu.com/p/68f22f9a00ee Spring Security 与 ...
- Spring Security 与 OAuth2(介绍)
https://www.jianshu.com/p/68f22f9a00ee Spring Security 与 OAuth2(介绍) 林塬 2018.01.23 11:14* 字数 3097 阅读 ...
- Spring Security基于Oauth2的SSO单点登录怎样做?一个注解搞定
一.说明 单点登录顾名思义就是在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统,免除多次登录的烦恼.本文主要介绍 同域 和 跨域 两种不同场景单点登录的实现原理,并使用 Spring ...
- spring security之 默认登录页源码跟踪
spring security之 默认登录页源码跟踪 2021年的最后2个月,立个flag,要把Spring Security和Spring Security OAuth2的应用及主流程源码研究透 ...
- Oauth2.0认证---授权码模式
目录: 1.功能描述 2.客户端的授权模式 3.授权模式认证流程 4.代码实现 1.功能描述 OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(au ...
- spring boot:spring security实现oauth2+jwt管理认证授权及oauth2返回结果格式化(spring boot 2.3.3)
一,为什么oauth2要整合jwt? 1,OAuth2的token技术有一个最大的问题是不携带用户信息,所以资源服务器不能进行本地验证, 以致每次对于资源的访问,资源服务器都需要向认证服务器的toke ...
随机推荐
- 为什么魂斗罗只有128KB却能实现那么长的剧情有答案了
PPU 首发公号:Rand_cs 本文继续讲述 NES 的基本原理,承接上文的 CPU,本文来讲述 PPU,较为复杂,慢慢来看.例子基本都是使用的魂斗罗,看完本文相信对那问题"为什么魂斗罗只 ...
- Linux扩展篇-shell编程(四)-shell条件判断
基本语法 格式一: test condition 格式二: [ condition ] 注意:1)condition前后要有空格.2)条件非空即为true,例如[ hello ]返回true,[ ]返 ...
- 命运2 Cross Save
epic 上免费领的命运2,进不去,界面提示要扫码. 解决方法: 1.手机或电脑浏览器进入:https://www.bungie.net/. 2.使用epic 账号登录 ,然后设置一个邮箱,邮箱收到验 ...
- 使用spark-sql处理Doris大表关联
背景 最近项目上有一个需求,需要将两张表(A表和B表)的数据进行关联并回写入其中一张表(A表),两张表都是分区表,但是关联条件不包括分区字段. 分析过程 方案一 最朴素的想法,直接关联执行,全表关联, ...
- Vector | Graph:蚂蚁首个开源Graph RAG框架设计解读
检索增强生成(RAG:Retrieval Augmented Generation)技术旨在把信息检索与大模型结合,以缓解大模型推理"幻觉"的问题.近来关于RAG的研究如火如荼,支 ...
- 支持TraceID、错误文件、错误行的第三方golang库:gerror
Gerr库简介 Golang第三方库 官方仓库:https://github.com/GuoFlight/gerror 特点: 兼容golang原生error库 gerror会自动生成traceID, ...
- /etc/shadow文件破解,密码破解,md5,SHA256,SHA512破解
环境 Kali系统 John the Ripper密码破解者 shadow文件解析 文件的格式为: {用户名}:{加密后的口令密码}:{口令最后修改时间距原点(1970-1-1)的天数}:{口令最小修 ...
- 如何在Spring Boot框架下实现高效的Excel服务端导入导出?
前言 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置 ...
- 【FAQ】HarmonyOS SDK 闭源开放能力 —Ads Kit
1.问题描述: 开屏广告效果最好的实现方式? 解决方法: 1.动画效果和开发者的实现方式有关,和开屏广告页面本身没什么关系的: 2.示例代码中使用Router跳转的方式展示广告,主要是用于演示广告接口 ...
- Linux 内核:RCU机制与使用
Linux 内核:RCU机制与使用 背景 学习Linux源码的时候,发现很多熟悉的数据结构多了__rcu后缀,因此了解了一下这些内容. 介绍 RCU(Read-Copy Update)是数据同步的一种 ...