国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Spring WebFlux Security結合R2DBC實現權限控制

開發 前端
我們這里對實現的原理做簡單的接收,主要核心是WebFilter。

環境:Springboot2.7.7

依賴管理

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>dev.miku</groupId>
<artifactId>r2dbc-mysql</artifactId>
<version>0.8.2.RELEASE</version>
</dependency>

配置管理

spring:
r2dbc:
url: r2dbc:mysql://localhost:3306/testjpa?serverZoneId=GMT%2B8
username: root
password: 123123
pool:
initialSize: 100
maxSize: 200
maxCreateConnectionTime: 30s
---
logging:
level:
'[org.springframework.r2dbc]': DEBUG

實體對象,Repository,Service

@Table("t_users")
public class Users implements UserDetails {
@Id
private Integer id ;
private String username ;
private String password ;
}

這里實體對象實現了UserDetials,在后續配置的ReactiveUserDetailsService 配置返回值必須是UserDetails

Repository接口

public interface UsersRepository extends ReactiveSortingRepository<Users, String> {
Mono<Users> findByUsername(String username);
}

Service類

@Service
public class UsersService {

@Resource
private R2dbcEntityTemplate template;
@Resource
private UsersRepository ur ;

public Mono<Users> queryUserByUsername(String username) {
return ur.findByUsername(username) ;
}

public Mono<Users> queryUserByUsernameAndPassword(String username, String password) {
return ur.findByUsernameAndPassword(username, password) ;
}

public Flux<Users> queryUsers() {
return template.select(Users.class).all() ;
}

}

數據庫中插入幾條數據

圖片

單元測試

@SpringBootTest
class SpringBootWebfluxSecurity2ApplicationTests {

@Resource
private UsersService usersService ;

@Test
public void testQueryUserByUsername() throws Exception {
usersService.queryUserByUsername("admin")
.doOnNext(System.out::println)
.subscribe() ;
System.in.read() ;
}

}

輸出

2023-01-12 17:43:48.863 DEBUG 16612 --- [           main] o.s.w.r.r.m.a.ControllerMethodResolver   : ControllerAdvice beans: none
2023-01-12 17:43:48.896 DEBUG 16612 --- [ main] o.s.w.s.adapter.HttpWebHandlerAdapter : enableLoggingRequestDetails='false': form data and headers will be masked to prevent unsafe logging of potentially sensitive data
2023-01-12 17:43:49.147 INFO 16612 --- [ main] ringBootWebfluxSecurity2ApplicationTests : Started SpringBootWebfluxSecurity2ApplicationTests in 1.778 seconds (JVM running for 2.356)
2023-01-12 17:43:50.141 DEBUG 16612 --- [actor-tcp-nio-2] o.s.r2dbc.core.DefaultDatabaseClient : Executing SQL statement [SELECT t_users.id, t_users.username, t_users.password FROM t_users WHERE t_users.username = ?]
Users [id=3, username=admin, password=123123]

正常,接下來就是進行Security的配置

@Configuration
@EnableReactiveMethodSecurity
public class ReactiveSecurityConfig {

// 根據用戶名查詢用戶信息
@Bean
public ReactiveUserDetailsService reativeUserDetailsService(UsersService usersService) {
return username -> usersService.queryUserByUsername(username).map(user -> {
return (UserDetails) user;
});
}
// 根據查詢出的用戶進行密碼比對,沒有對密碼進行加密所有就進行簡單的equals比較
@Bean
public PasswordEncoder passwordEncoder() {
return new PasswordEncoder() {
@Override
public String encode(CharSequence rawPassword) {
return rawPassword.toString();
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return rawPassword.toString().equals(encodedPassword);
}
};
}
@Order(Ordered.HIGHEST_PRECEDENCE + 1)
@Bean
public SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
http.authorizeExchange((authorize) ->
authorize
// 配置資源訪問權限,對于靜態資源直接放行
.pathMatchers("/resources/**", "/favicon.ico").permitAll()
// /users開頭的接口必須擁有ROLE_ADMIN角色
.pathMatchers("/users/**").hasRole("ADMIN")
// /api開頭的接口通過自定義驗證邏輯控制
.pathMatchers("/api/**").access((authentication, context) -> {
return authentication.map(auth -> {
if ("user1".equals(auth.getName())) {
return new AuthorizationDecision(false);
}
MultiValueMap<String, String> params = context.getExchange().getRequest().getQueryParams();
List<String> sk = params.get("sk");
if (sk == null || sk.get(0).equals("u")) {
return new AuthorizationDecision(false);
}
return new AuthorizationDecision(true);
});
}).anyExchange().authenticated());
// 異常處理
http.exceptionHandling(execSpec -> {
// 無權限時響應策略
execSpec.accessDeniedHandler((exchange, denied) -> {
ServerHttpResponse response = exchange.getResponse() ;
response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
DataBuffer body = response.bufferFactory().allocateBuffer() ;
body.write("無權限 - " + denied.getMessage(), StandardCharsets.UTF_8) ;
return response.writeWith(Mono.just(body)) ;
}) ;
// 沒有登錄配置統一認證入口,這里默認系統提供的登錄頁面
execSpec.authenticationEntryPoint((exchange, ex) -> {
ServerHttpResponse response = exchange.getResponse() ;
response.getHeaders().add("Content-Type", "text/html;charset=UTF-8");
DataBuffer body = response.bufferFactory().allocateBuffer() ;
body.write("請先登錄 - " + ex.getMessage(), StandardCharsets.UTF_8) ;
return response.writeWith(Mono.just(body)) ;
}) ;
}) ;
http.csrf(csrf -> csrf.disable());
http.formLogin();
return http.build();
}

}

以上就是Security的配置。這里就不做測試了

原理

這里對實現的原理做簡單的接收,主要核心是WebFilter

自動配置類中

public class ReactiveSecurityAutoConfiguration {
// 這里通過注解啟用了Security功能
@EnableWebFluxSecurity
static class EnableWebFluxSecurityConfiguration {
}
}

EnableWebFluxSecurity

@Import({ ServerHttpSecurityConfiguration.class, WebFluxSecurityConfiguration.class,
ReactiveOAuth2ClientImportSelector.class })
@Configuration
public @interface EnableWebFluxSecurity {
}

這里有個重要的ServerHttpSecurityConfiguration和WebFluxSecurityConfiguration配置類

@Configuration(proxyBeanMethods = false)
class ServerHttpSecurityConfiguration {
// 該類用來自定義配置我們的信息,也就是上面我們自定義的SecurityWebFilterChain
// 通過ServerHttpSecurity構建SecurityWebFilterChain
@Bean(HTTPSECURITY_BEAN_NAME)
@Scope("prototype")
ServerHttpSecurity httpSecurity() {
ContextAwareServerHttpSecurity http = new ContextAwareServerHttpSecurity();
return http.authenticationManager(authenticationManager())
.headers().and()
.logout().and();
}
}

WebFluxSecurityConfiguration

配置類最主要就是用來配置一個WebFilter

@Configuration(proxyBeanMethods = false)
class WebFluxSecurityConfiguration {
private List<SecurityWebFilterChain> securityWebFilterChains;
// 注入當前系統中的所有SecurityWebFilterChain,主要就是我們自定義實現的該類型
@Autowired(required = false)
void setSecurityWebFilterChains(List<SecurityWebFilterChain> securityWebFilterChains) {
this.securityWebFilterChains = securityWebFilterChains;
}
@Bean(SPRING_SECURITY_WEBFILTERCHAINFILTER_BEAN_NAME)
@Order(WEB_FILTER_CHAIN_FILTER_ORDER)
WebFilterChainProxy springSecurityWebFilterChainFilter() {
return new WebFilterChainProxy(getSecurityWebFilterChains());
}
private List<SecurityWebFilterChain> getSecurityWebFilterChains() {
List<SecurityWebFilterChain> result = this.securityWebFilterChains;
if (ObjectUtils.isEmpty(result)) {
return Arrays.asList(springSecurityFilterChain());
}
return result;
}
}

WebFilterChainProxy核心過濾器

public class WebFilterChainProxy implements WebFilter {

private final List<SecurityWebFilterChain> filters;
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return Flux.fromIterable(this.filters)
.filterWhen((securityWebFilterChain) -> securityWebFilterChain.matches(exchange)).next()
.switchIfEmpty(chain.filter(exchange).then(Mono.empty()))
.flatMap((securityWebFilterChain) -> securityWebFilterChain.getWebFilters().collectList())
.map((filters) -> new FilteringWebHandler(chain::filter, filters)).map(DefaultWebFilterChain::new)
.flatMap((securedChain) -> securedChain.filter(exchange));
}

}

以上就是WebFlux中應用Security的原理

責任編輯:武曉燕 來源: 實戰案例錦集
相關推薦

2023-09-21 08:01:27

SpringR2DBC實現數據庫

2022-03-29 07:32:38

R2DBC數據庫反應式

2025-05-16 08:55:58

2022-08-15 08:42:46

權限控制Spring

2022-08-15 08:45:21

Spring權限控制

2022-08-30 08:36:13

Spring權限控制

2022-08-30 08:55:49

Spring權限控制

2022-08-30 08:43:11

Spring權限控制

2022-08-30 08:50:07

Spring權限控制

2020-05-08 10:34:30

Spring非阻塞編程

2022-06-16 10:38:24

URL權限源代碼

2024-02-18 12:44:22

2020-06-17 08:31:10

權限控制Spring Secu

2021-07-27 10:49:10

SpringSecurity權限

2025-03-13 07:33:46

Spring項目開發

2020-09-16 08:07:54

權限粒度Spring Secu

2022-11-04 11:44:56

WebFluxCURDWeb

2011-03-01 16:44:02

Hyper-V Ser

2022-01-07 07:29:08

Rbac權限模型

2020-05-25 07:00:00

雙因素認證身份認證密碼
點贊
收藏

51CTO技術棧公眾號

欧美日韩另类一区| 亚洲一区二区日本| 深夜影院在线观看| 久久在线免费观看| 中文字幕精品在线播放| 欧美私人啪啪vps| 97在线观看视频| 欧美男女视频| 国产一区二区激情| 日韩电影大全网站| 亚洲精品影视在线观看| 国内老司机av在线| 精品国产成人在线影院| 大片免费在线看视频| 欧美日韩亚洲不卡| 超碰国产在线观看| 欧洲在线/亚洲| 欧美美女搞黄| 91久久香蕉国产日韩欧美9色| 亚洲一区二区三区成人| 亚洲另类春色国产| 色琪琪丁香婷婷综合久久| 亚洲欧美国产77777| 日本高清视频网站www| 亚洲综合视频在线| 在线免费日韩| 婷婷六月综合亚洲| 九色蝌蚪在线| 在线播放91灌醉迷j高跟美女 | 精品va天堂亚洲国产| 色呦呦在线视频| 亚洲精品国产福利| 姬川优奈av一区二区在线电影| 中文字幕日韩av电影| 久久久久久久久成人| 热草久综合在线| 日韩免费高清| y111111国产精品久久婷婷| 亚洲国产1区| 在线一区亚洲| 久久色在线观看| 开心丁香婷婷深爱五月| 欧美日韩免费一区| 在线观看电影av| 中文字幕在线国产精品| 五月国产精品| 成人18视频| 久草中文综合在线| 日韩av片网站| 色av成人天堂桃色av| 9999精品成人免费毛片在线看| 色偷偷亚洲男人天堂| 国产探花在线精品| 日韩欧美一区二区三区四区五区 | 日韩三级影视| 久久久女人电视剧免费播放下载| 欧美日韩在线播放视频| 免费国产一区二区| 26uuu国产在线精品一区二区| 精东影业在线观看| 精品国产乱码久久久久久1区2区| **日韩最新| 91在线中文字幕| 激情综合网最新| 国产真实伦在线观看| 欧美日韩高清一区二区不卡| 久久91视频| 91在线国产电影| 国产99久久久精品| 小小水蜜桃在线观看| 亚洲少妇激情视频| 久久精品影视| 人妻熟妇乱又伦精品视频| 在线免费观看日韩欧美| 亚洲精品成人一区| 国产精品对白刺激久久久| 成人午夜私人影院| 国产毛片在线| 欧美日本在线视频中文字字幕| 国产精品v一区二区三区| 日韩黄色短视频| 色乱码一区二区三区88| 久久亚洲国产精品尤物| 9a蜜桃久久久久久免费| 成人av在线电影| а天堂8中文最新版在线官网| 欧美高清视频免费观看| 日韩av中文字幕一区二区| jizz蜜桃视频在线观看| 亚洲精品视频中文字幕| 欧美色图首页| 免费羞羞视频| 久久精品国产96久久久香蕉 | 欧美资源在线观看| 久久99久久久久| 成人免费高清在线播放| 国语自产在线不卡| 国产v日产∨综合v精品视频| 高清日韩av电影| 91成人性视频| 国产999精品久久| 97caopor国产在线视频| 成人免费视频97| 亚洲天堂久久久久久久| 99久久久成人国产精品| 特级黄色录像片| 91精品国产综合久久久久久| 久久久久av| 黄色一级视频播放| 亚洲片在线资源| 这里只有精品在线播放| 天涯成人国产亚洲精品一区av| 黄色高清无遮挡| 国产在线播放不卡| 国产91网红主播在线观看| 午夜一区不卡| 特黄特色欧美大片| 国产毛片视频| 国产在线精品一区二区中文| 精品国产伦一区二区三区观看方式| 国产精品久久久久久久裸模 | 三级在线看中文字幕完整版| 2019中文字幕在线视频| 艹b视频在线观看| 超碰97在线看| 亚洲永久激情精品| 中文字幕一区二区三区最新| 国产不卡一区二区在线播放| 91麻豆精东视频| 久久三级视频| 99热在线成人| 日韩一区二区中文| 韩日在线视频| 向日葵污视频在线观看| 久久精品国产一区二区三区日韩| 国产精品一码二码三码在线| 欧美一区视频在线| 国产亚洲精品久久久久久牛牛| 在线播放日韩专区| 亚洲国产毛片完整版| 97久久精品人人做人人爽50路| 亚洲午夜三级在线| 26uuu国产在线精品一区二区| 一区二区三区中文字幕精品精品 | av网站无病毒在线| 国产91精品入口17c| 精品网站在线看| 国产无限制自拍| 免费看av软件| 久久久久久欧美精品色一二三四| 99re视频在线播放| 成人自拍爱视频| 国产午夜精品在线| 性欧美精品一区二区三区在线播放 | 色yeye香蕉凹凸一区二区av| 精品亚洲一区二区三区在线播放| 中文字幕精品久久| 欧美激情国产日韩精品一区18| 日韩免费观看av| 欧美孕妇与黑人孕交| 在线精品亚洲一区二区| 波多野结衣之无限发射| 国产黄色免费电影| 美女航空一级毛片在线播放| 欧美亚洲综合一区| 亚洲一区在线播放| 午夜精品爽啪视频| 国产欧美日本| 蜜臀a∨国产成人精品| 久久草av在线| 日本一区二区免费在线观看视频 | 欧美性一二三区| 久久精品亚洲94久久精品| 欧美中文在线观看| 麻豆久久久9性大片| 天堂精品视频| av天堂永久资源网| 日本高清中文字幕在线| 美国成人毛片| 亚洲精品视频网上网址在线观看| 国产精一区二区三区| 蜜桃精品一区二区三区| 久久白虎精品| 亚洲欧美日韩综合一区| 久久久久亚洲精品国产| 欧美在线观看18| 99精品久久只有精品| 在线成人激情| 色综合天天色| 十九岁完整版在线观看好看云免费| 杨幂一区欧美专区| 热99久久精品| 亚洲精品国产电影| 亚洲视频在线观看一区| 日本不卡视频一二三区| 久久1电影院| 青草在线视频在线观看| 日本19禁啪啪吃奶大尺度| 91成人在线视频观看| 亚洲xxx视频|