使用反应登录表单在 Spring Boot 中对用户进行身份验证

GaB*_*GaB 5 authentication spring spring-security reactjs spring-boot

我已经为我的项目添加了 spring 安全性,我正在尝试进行用户身份验证。我正在使用 CrudRepository 查找用户并验证详细信息是否正确。我已经能够使用开箱即用的登录页面来让它工作。我的问题是我想通过我的反应登录页面对用户进行身份验证。Spring boot 应用程序为 8080,而 react 应用程序为 3000。我见过自定义登录页面设置,但登录页面与 spring boot 应用程序位于同一位置。我的问题是,登录页面是否有可能位于其他地方,是否有登录端点可以发送我的请求来验证用户身份?或者我可以添加一些配置来告诉 spring 使用来自前端的用户详细信息来验证用户。

一方面,我不明白不应该使用 NoOpPasswordEncoder,这只是一个 POC,不会投入生产。谢谢

我的安全配置文件如下所示:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService)
}

@Override
protected void configure(HttpSecurity http) throws Exception {
             http
            .authorizeRequests()
            .antMatchers("/**").hasRole("ADMIN")
            .and()
            .formLogin();
}

@Bean
public PasswordEncoder getPasswordEncoder(){
    return NoOpPasswordEncoder.getInstance();
}
Run Code Online (Sandbox Code Playgroud)

UserDetailsS​​erviceImpl:

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
private UserRepository userRepository;

public UserDetailsServiceImpl(UserRepository userRepository) {
    this.userRepository = userRepository;
}


@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
    Optional< UserEntity > user= userRepository.findByEmail(email);
    user.orElseThrow(()-> new UsernameNotFoundException("Not found: " + email));
    return user.map(UserInfo::new).get();
}
Run Code Online (Sandbox Code Playgroud)

}

用户详细信息Impl

public class UserInfo implements UserDetails {
private String userName;
public UserInfo(UserEntity userEntity){
this.userName=userEntity.getEmail();
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    return Arrays.asList(new SimpleGrantedAuthority("ADMIN"));
}

@Override
public String getPassword() {
    return "TestPassword";
}

@Override
public String getUsername() {
    return userName;
}

@Override
public boolean isAccountNonExpired() {
    return true;
}

@Override
public boolean isAccountNonLocked() {
    return true;
}

@Override
public boolean isCredentialsNonExpired() {
    return true;
}

@Override
public boolean isEnabled() {
    return true;
}
Run Code Online (Sandbox Code Playgroud)

}

春季安全日志:

创建过滤器链:任何请求,[org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@4529048e,org.springframework.security.web.context.SecurityContextPersistenceFilter@c247b02,org.springframework.security.web.header。 HeaderWriterFilter@ecfff32, org.springframework.web.filter.CorsFilter@6addfa22, org.springframework.security.web.csrf.CsrfFilter@629cf53c, org.springframework.security.web.authentication.logout.LogoutFilter@7b38db21.org.spring security.web.authentication.UsernamePasswordAuthenticationFilter@3b18009f, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@78f1d29, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@15405ba1, org.springframework.security.web. 74b521c,org.springframework.security。web.session.SessionManagementFilter@3c65f2e1,org.springframework.security.web.access.ExceptionTranslationFilter@531b1778,org.springframework.security.web.access.intercept.FilterSecurityInterceptor@458704ee]

小智 2

在开发时,您可以在 package.json 文件中输入以下内容:

"proxy": "http://localhost:8080/"
Run Code Online (Sandbox Code Playgroud)

至于Java Web应用程序,您可以提供自定义身份验证请求匹配器和身份验证入口点:

@Autowired
RestAuthEntryPoint restAuthEntryPoint;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
        .antMatchers("/**").hasRole("ADMIN")
        .and()
        .exceptionHandling()
        .authenticationEntryPoint(restAuthEntryPoint) <- to support REST
        .and()
        .formLogin().loginProcessingUrl("/fooLogin"); <- credentials checked here
}
Run Code Online (Sandbox Code Playgroud)

支持 REST 并处理未经授权的访问:

@Component
public class RestAuthEntryPoint implements AuthenticationEntryPoint{


@Override
public void commence(
        HttpServletRequest request,
        HttpServletResponse response,
        AuthenticationException authException) throws IOException {

    // send error response to the client (401 unauthorized)
    response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized" );
}
Run Code Online (Sandbox Code Playgroud)

}

React中的登录表单提交(基本):

 axios({
         method:'post',
         url:'//fooLogin',
         params:{
                username: this.state.email,
                password: this.state.password
            },
         config: { headers: {'Content-Type': 'application/x-www-form-urlencoded'}}
        })
        .then(
            //authentication success...
        })
        .catch(error=>{
            var errResp = error.response;
            if(errResp.status === 401){
               //Ex: show login page again...
            }

        })
Run Code Online (Sandbox Code Playgroud)