oauth password模式_Spring Boot Security Oauth2之客户端模式及密码模式实现

论坛 期权论坛 脚本     
已经匿名di用户   2022-3-21 23:59   2155   0

Spring Boot Security Oauth2之客户端模式及密码模式实现

示例主要内容

1.多认证模式(密码模式、客户端模式)

2.token存到redis支持

3.资源保护

4.密码模式用户及权限存到数据库

5.使用说明

介绍

oauth2 client credentials 客户端模式获取access_token流程

客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行认证。严格地说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务,其实不存在授权问题。

(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。客户端发出的HTTP请求,包含以下参数:

granttype:表示授权类型,此处的值固定为"clientcredentials",必选项。

scope:表示权限范围,可选项。

(B)认证服务器确认无误后,向客户端提供访问令牌。

oauth2 password 密码模式获取access_token流程

密码模式(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向"服务商提供商"索要授权。

在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或者由一个著名公司出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。

(A)用户向客户端提供用户名和密码。

(B)客户端将用户名和密码发给认证服务器,向后者请求令牌。 客户端发出的HTTP请求,包含以下参数:

grant_type:表示授权类型,此处的值固定为"password",必选项。

username:表示用户名,必选项。

password:表示用户的密码,必选项。

scope:表示权限范围,可选项。

(C)认证服务器确认无误后,向客户端提供访问令牌。

Oauth2提供的默认端点(endpoints)

/oauth/authorize:授权端点

/oauth/token:令牌端点

/oauth/confirm_access:用户确认授权提交端点

/oauth/error:授权服务错误信息端点

/oauth/check_token:用于资源服务访问的令牌解析端点

/oauth/token_key:提供公有密匙的端点,如果使用JWT令牌的话

示例使用介绍

1.端模式获取access_token

返回结果

{

"access_token": "67a2c8f6-bd08-4409-a0d6-6ba61a4be950",

"token_type": "bearer",

"expires_in": 41203,

"scope": "select"

}

2.密码模式获取access_token

返回结果

{

"access_token": "b3d2c131-1225-45b4-9ff5-51ec17511cee",

"token_type": "bearer",

"refresh_token": "8495d597-0560-4598-95ef-143c0855363c",

"expires_in": 42417,

"scope": "select"

}

3.刷新access_token

返回结果

{

"access_token": "63de6c71-672f-418c-80eb-0c9abc95b67c",

"token_type": "bearer",

"refresh_token": "8495d597-0560-4598-95ef-143c0855363c",

"expires_in": 43199,

"scope": "select"

}

4.访问受保护的资源

正确返回数据

spring security oauth2代码过程

security oauth2 整合的3个核心配置类

1.资源服务配置 ResourceServerConfiguration

2.授权认证服务配置 AuthorizationServerConfiguration

3.security 配置 SecurityConfiguration

1.pom.xml添加maven依赖

org.springframework.boot

spring-boot-starter-security

org.springframework.security.oauth

spring-security-oauth2

2.3.6.RELEASE

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-data-redis

org.springframework.boot

spring-boot-starter-thymeleaf

org.springframework.boot

spring-boot-starter-test

test

mysql

mysql-connector-java

8.0.17

com.baomidou

mybatis-plus-boot-starter

3.1.2

org.projectlombok

lombok

true

cn.hutool

hutool-all

4.6.1

test

主要使用了:security、oauth2、redis、mysql、mybatis-plus等组件

2.认证授权配置AuthorizationServerConfigurerAdapter.java

@Configuration

@EnableAuthorizationServer

public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

private static final String RESOURCE_IDS = "order";

@Autowired

AuthenticationManager authenticationManager;

@Autowired

RedisConnectionFactory redisConnectionFactory;

@Autowired

private UserDetailsService userDetailsService;

@Override

public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

String finalSecret = "{bcrypt}" + new BCryptPasswordEncoder().encode("123456");

//配置两个客户端,一个用于password认证一个用于client认证

clients.inMemory()

//client模式

.withClient("client_1")

.resourceIds(RESOURCE_IDS)

.authorizedGrantTypes("client_credentials", "refresh_token")

.scopes("select")

.authorities("oauth2")

.secret(finalSecret)

.and()

//密码模式

.withClient("client_2")

.resourceIds(RESOURCE_IDS)

.authorizedGrantTypes("password", "refresh_token")

.scopes("select")

.authorities("oauth2")

.secret(finalSecret);

}

/**

* 认证服务端点配置

*/

@Override

public void configure(AuthorizationServerEndpointsConfigurer endpoints) {

endpoints

//用户管理

.userDetailsService(userDetailsService)

//token存到redis

.tokenStore(new RedisTokenStore(redisConnectionFactory))

//启用oauth2管理

.authenticationManager(authenticationManager)

//接收GET和POST

.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);

}

@Override

public void configure(AuthorizationServerSecurityConfigurer oauthServer) {

oauthServer.allowFormAuthenticationForClients();

}

}

3.资源配置ResourceServerConfig.java

@Configuration

@EnableResourceServer

public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

private static final String RESOURCE_IDS = "order";

@Override

public void configure(ResourceServerSecurityConfigurer resources) {

resources.resourceId(RESOURCE_IDS).stateless(true);

}

@Override

public void configure(HttpSecurity httpSecurity) throws Exception {

httpSecurity

.authorizeRequests()

.antMatchers("/order/**").authenticated(); //配置order访问控制,必须认证过后才可以访问

}

}

4.密码模式的用户及权限存到了数据库,UserDetailsServiceImpl.java

@Service

public class UserDetailsServiceImpl implements UserDetailsService {

@Autowired

private UserServiceImpl userService;

/**

* 实现UserDetailsService中的loadUserByUsername方法,用于加载用户数据

*/

@Override

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

User user = userService.queryUserByUsername(username);

if (user == null) {

throw new UsernameNotFoundException("用户不存在");

}

//用户权限列表

Collection extends GrantedAuthority> authorities = userService.queryUserAuthorities(user.getId());

return new AuthUser(

user.getId(),

user.getUsername(),

user.getPassword(),

true,

true,

true,

true,

authorities);

}

}

5.WebSecurityConfig配置

@Configuration

@EnableWebSecurity

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Bean

PasswordEncoder passwordEncoder() {

return PasswordEncoderFactories.createDelegatingPasswordEncoder();

}

/**

* 注入AuthenticationManager接口,启用OAuth2密码模式

*

* @return

* @throws Exception

*/

@Bean

@Override

public AuthenticationManager authenticationManagerBean() throws Exception {

AuthenticationManager manager = super.authenticationManagerBean();

return manager;

}

/**

* 通过HttpSecurity实现Security的自定义过滤配置

*

* @param httpSecurity

* @throws Exception

*/

@Override

protected void configure(HttpSecurity httpSecurity) throws Exception {

httpSecurity

.requestMatchers().anyRequest()

.and()

.authorizeRequests()

.antMatchers("/oauth/**").permitAll();

}

}

6.application.yml配置

server:

port: 8080

spring:

thymeleaf:

encoding: UTF-8

cache: false

datasource:

driver-class-name: com.mysql.cj.jdbc.Driver

url: jdbc:mysql://localhost:3306/easy_web?useSSL=false&serverTimezone=UTC

username: root

password: 123456

redis:

host: 127.0.0.1

port: 6379

password:

logging.level.org.springframework.security: DEBUG

7.inital.sql数据库初始化脚本

DROP TABLE IF EXISTS `user`;

DROP TABLE IF EXISTS `role`;

DROP TABLE IF EXISTS `user_role`;

DROP TABLE IF EXISTS `role_permission`;

DROP TABLE IF EXISTS `permission`;

CREATE TABLE `user` (

`id` bigint(11) NOT NULL AUTO_INCREMENT,

`username` varchar(255) NOT NULL,

`password` varchar(255) NOT NULL,

PRIMARY KEY (`id`)

);

CREATE TABLE `role` (

`id` bigint(11) NOT NULL AUTO_INCREMENT,

`name` varchar(255) NOT NULL,

PRIMARY KEY (`id`)

);

CREATE TABLE `user_role` (

`id` bigint(11) NOT NULL AUTO_INCREMENT,

`user_id` bigint(11) NOT NULL,

`role_id` bigint(11) NOT NULL,

PRIMARY KEY (`id`)

);

CREATE TABLE `role_permission` (

`id` bigint(11) NOT NULL AUTO_INCREMENT,

`role_id` bigint(11) NOT NULL,

`permission_id` bigint(11) NOT NULL,

PRIMARY KEY (`id`)

);

CREATE TABLE `permission` (

`id` bigint(11) NOT NULL AUTO_INCREMENT,

`url` varchar(255) NOT NULL,

`name` varchar(255) NOT NULL,

`description` varchar(255) NULL,

`pid` bigint(11) NOT NULL,

PRIMARY KEY (`id`)

);

INSERT INTO user (id, username, password) VALUES (1,'user','{bcrypt}$2a$10$Tme77eHtXzcB8ghQUepYguJr7P7ESg0Y7XHMnk60s.kf2A.BWBD9m');

INSERT INTO user (id, username , password) VALUES (2,'admin','{bcrypt}$2a$10$Tme77eHtXzcB8ghQUepYguJr7P7ESg0Y7XHMnk60s.kf2A.BWBD9m');

INSERT INTO role (id, name) VALUES (1,'USER');

INSERT INTO role (id, name) VALUES (2,'ADMIN');

INSERT INTO permission (id, url, name, pid) VALUES (1,'/user/common','common',0);

INSERT INTO permission (id, url, name, pid) VALUES (2,'/user/admin','admin',0);

INSERT INTO user_role (user_id, role_id) VALUES (1, 1);

INSERT INTO user_role (user_id, role_id) VALUES (2, 1);

INSERT INTO user_role (user_id, role_id) VALUES (2, 2);

INSERT INTO role_permission (role_id, permission_id) VALUES (1, 1);

INSERT INTO role_permission (role_id, permission_id) VALUES (2, 1);

INSERT INTO role_permission (role_id, permission_id) VALUES (2, 2);

经过以上七个步骤,我们快速实现了Oauth2的密码模式和客户模式功能。

资料

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:81
帖子:4969
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP