我正在使用 Spring Boot 撰寫一個簡單的 REST API,并且我想啟用基本身份驗證。因此我使用了如下所示的 WebSecurityConfigurerAdapter。為簡單起見,我只想檢查密碼(pwd123)并允許任何用戶登錄。請參考下面的代碼。
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(new AuthenticationProvider() {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (authentication == null || authentication.getCredentials() == null) {
throw new BadCredentialsException("Bad credentials");
}
if (authentication.getCredentials().equals("pwd123")) {
return new UsernamePasswordAuthenticationToken(authentication.getName(),
authentication.getCredentials().toString(),
Collections.emptyList());
}
return null;
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
});
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and().httpBasic();
}
}
假設 user_A 使用有效密碼(即 pwd123)訪問了 REST API,然后使用錯誤密碼執行發送 API 呼叫。但是,允許用戶訪問 API,這是問題所在。
當我進行除錯時,我意識到Spring Security 中的BasicAuthenticationFilter類中的authenticationIsRequired函式在這種情況下回傳 false。請參考該代碼。
private boolean authenticationIsRequired(String username) {
// Only reauthenticate if username doesn't match SecurityContextHolder and user
// isn't authenticated (see SEC-53)
Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication();
if (existingAuth == null || !existingAuth.isAuthenticated()) {
return true;
}
// Limit username comparison to providers which use usernames (ie
// UsernamePasswordAuthenticationToken) (see SEC-348)
if (existingAuth instanceof UsernamePasswordAuthenticationToken && !existingAuth.getName().equals(username)) {
return true;
}
// Handle unusual condition where an AnonymousAuthenticationToken is already
// present. This shouldn't happen very often, as BasicProcessingFitler is meant to
// be earlier in the filter chain than AnonymousAuthenticationFilter.
// Nevertheless, presence of both an AnonymousAuthenticationToken together with a
// BASIC authentication request header should indicate reauthentication using the
// BASIC protocol is desirable. This behaviour is also consistent with that
// provided by form and digest, both of which force re-authentication if the
// respective header is detected (and in doing so replace/ any existing
// AnonymousAuthenticationToken). See SEC-610.
return (existingAuth instanceof AnonymousAuthenticationToken);
}
請讓我知道我的實施中缺少什么
uj5u.com熱心網友回復:
如評論中所述,AuthenticationProvider您可以嘗試提供自定義,而不是提供自定義UserDetailsService。這是完整的配置:
@EnableWebSecurity
public class SecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests((authorizeRequests) -> authorizeRequests
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults());
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
return (username) -> new User(username, "{noop}pwd123", AuthorityUtils.createAuthorityList("ROLE_USER"));
}
}
當您演變為通過第三方服務查找用戶時,您可以在自定義UserDetailsService(lambda 函式或實作介面的實際類)中添加代碼來執行此操作,并繼續回傳org.springframework.security.core.userdetails.User.
注意:我實際上并不推薦在生產中使用純文本密碼。你會{noop}pwd123用類似的東西替換{bcrypt}<bcrypt encoded password here>。
uj5u.com熱心網友回復:
正如評論和答案中所建議的那樣,即使您使用InMemoryUserDetailsManager 問題也沒有得到解決,這意味著,一旦用戶使用正確的用戶名和密碼進行身份驗證,他的密碼在隨后的 REST API 呼叫中不會被驗證,即可以使用任何密碼。這是因為BasicAuthenticationFilter類中的功能會跳過擁有有效 JSESSION cookie 的用戶。
要解決這個問題,我們應該配置 http 以通過以下方式創建無狀態會話
http .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
在configure功能上WebSecurityConfigurerAdapter
請參閱為什么 Spring Security 中的 BasicAuthenticationFilter 僅匹配用戶名而不匹配密碼
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/472566.html
上一篇:帶有“param”引數的@RequestMapping無法正常作業
下一篇:java.lang.NoSuchMethodException部署在tomcat上時Spring-bootWeb應用程式中的錯誤
