Skip to content

Commit

Permalink
fix: basic auth issue that not set Authentication in SecurityContextH…
Browse files Browse the repository at this point in the history
…older (#643)
  • Loading branch information
ChiveHao committed Aug 8, 2024
1 parent 78e6532 commit 299b8b2
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 2 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

更新日志文档,版本顺序从新到旧,最新版本在最前(上)面。

# 0.15.1

## 问题修复

- Basic认证成功后没有设置Authentication到SecurityContextHolder,导致收藏接口403异常

# 0.15.0

## 新特性
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=0.15.0
version=0.15.1
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
package run.ikaros.server.security.authentication.basicauth;

import org.springframework.security.config.Customizer;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.stereotype.Component;
import run.ikaros.server.security.authentication.SecurityConfigurer;

@Component
public class BasicAuthenticationConfigurer implements SecurityConfigurer {
private final BasicAuthenticationFilter basicAuthenticationFilter;

public BasicAuthenticationConfigurer(BasicAuthenticationFilter basicAuthenticationFilter) {
this.basicAuthenticationFilter = basicAuthenticationFilter;
}

@Override
public void configure(ServerHttpSecurity http) {
http.httpBasic(Customizer.withDefaults());
http.httpBasic(Customizer.withDefaults())
.addFilterAfter(basicAuthenticationFilter, SecurityWebFiltersOrder.AUTHENTICATION);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package run.ikaros.server.security.authentication.basicauth;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

@Slf4j
@Component
public class BasicAuthenticationFilter implements WebFilter {
private final ReactiveUserDetailsService userDetailsService;

public BasicAuthenticationFilter(ReactiveUserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}


@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
String basic64 =
extractBasic64(exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION));
if (basic64 != null) {
String decoder =
new String(Base64.getDecoder().decode(basic64), StandardCharsets.UTF_8);
if (!decoder.contains(":")) {
return Mono.empty();
}
String[] split = decoder.split(":");
String username = split[0];
String password = split[1];
return userDetailsService.findByUsername(username)
.map(userDetails -> new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities()))
.map(authenticationToken -> {
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
return authenticationToken;
})
.map(ReactiveSecurityContextHolder::withAuthentication)
.flatMap(context -> chain.filter(exchange).contextWrite(context));
}
return chain.filter(exchange);
}

private String extractBasic64(String bearerToken) {
if (bearerToken != null && bearerToken.startsWith("Basic ")) {
return bearerToken.substring(6);
}
return null;
}
}

0 comments on commit 299b8b2

Please sign in to comment.