gpt4 book ai didi

java - Spring 安全: get password in UserDetailsServiceMethod

转载 作者:行者123 更新时间:2023-12-02 01:48:03 25 4
gpt4 key购买 nike

为了获得我的帐户,我需要登录一个外部 spring 应用程序。为什么我需要它并不重要,但为了在 API 上执行/login 调用,我需要在 UserDetailsS​​erviceMethod 中获取密码。这是我的安全设置:

//https://auth0.com/blog/implementing-jwt-authentication-on-spring-boot/
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
private UserDetailsService userDetailsService;
private BCryptPasswordEncoder bCryptPasswordEncoder;

//Constructor gets authLogic for external authentication
@Autowired
public WebSecurity(@Qualifier("authLogic") UserDetailsService userDetailsService){
this.userDetailsService = userDetailsService;
this.bCryptPasswordEncoder = new BCryptPasswordEncoder();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.authorizeRequests()
.antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html", "/webjars/**", "/swagger-resources/configuration/ui", "/swagger-resources/configuration/security").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}

@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList(BANK_API, INVENTORY_API, MARKET_API)); //TODO: is dit correct??
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "PATCH"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.setExposedHeaders(Arrays.asList("X-Auth-Token","Authorization","Access-Control-Allow-Origin","Access-Control-Allow-Credentials"));

final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}

我的 UserDetailsS​​erviceMethod 实现:

@Service
public class AuthLogic implements UserDetailsService {
private HttpServletRequest request;
private IAccountRepository accountRepository;
private RestCallLogic restCall;

@Autowired
public AuthLogic(HttpServletRequest request, IAccountRepository accountRepository, RestCallLogic restCall){
this.request = request;
this.accountRepository = accountRepository;
this.restCall = restCall;
}

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//get password
//make restcall to external login
}
}

有没有办法在使用 Spring Security 实现时获取密码。因为我可以轻松地创建自己的类并从那里进行登录,但最好使用 Spring 安全性。此外,登录还会返回一个 token ,我可以将其重新设置为用户。也许是我想多了...

为了进行 API 调用,我需要编写一个自定义 AuthenticationProvider:

@Component
public class JwtAuthenticationProvider implements AuthenticationProvider {

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {

String username = authentication.getName();
String password = authentication.getCredentials().toString();

UserDetails principal = new User(username, password, new ArrayList<>());

return new UsernamePasswordAuthenticationToken(principal, password, new ArrayList<>());
}

@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}

最佳答案

在幕后,Spring Security 解析过滤器中的用户凭据(例如 BasicAuthenticationFilterUsernamePasswordAuthenticationFilter 等 - 过滤器检索用户凭据),如果此类过滤器成功检索用户凭据,则会将这些凭据传递给 AuthenticationProvider验证凭据并创建用户的详细信息 ( read more about AuthenticationProvider )。 AuthenticationProvider可以通过各种方式验证凭据。

执行之一AuthenticationProviderDaoAuthenticationProvider它尝试通过 UserDetailsService 中的用户名查找用户如果发现它会得到 UserDetails对于 UserDetailsService 的用户然后检查用户提供的密码是否满足UserDetails中的密码.

在您的情况下,您需要不在 UserDetailsService 中提出此类请求,但是在 AuthenticationProvider因为它对这种情况负责。

我的建议是延长 AbstractUserDetailsAuthenticationProvider来自 spring security 的类并以抽象方法实现您的功能 protected abstract UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException; .

例如:

@Configuration
public class WebSecurityConf43547 extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(new AbstractUserDetailsAuthenticationProvider() {
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) throws AuthenticationException {
//from docs: "[...]Generally a subclass will at least compare the
//Authentication.getCredentials() with a UserDetails.getPassword() [...]"
}

@Override
protected UserDetails retrieveUser(String s, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) throws AuthenticationException {
usernamePasswordAuthenticationToken.getCredentials();
//your api here
}
});
}
}

更好的例子:看看如何 DaoAuthenticationProvider延伸AbstractUserDetailsAuthenticationProvider在 Spring 安全中。

关于java - Spring 安全: get password in UserDetailsServiceMethod,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53445809/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com