对预检请求的响应未通过访问控制检查:不存在“ Access-Control-Allow-Origin”标头... Spring Security-React

时间:2020-11-11 09:30:49

标签: java spring spring-security cors authorization

我正在尝试将Spring Security身份验证添加到我的完整堆栈Web应用程序中,该应用程序存在于Java-Spring Boot后端中,该后端使用JPA与数据库进行通信并从React前端接收HTTP请求。我遇到了一个问题,即一旦将身份验证添加到后端方法中,尝试调用它们时,前端就会出现CORS错误。我尝试过发送没有授权标头的请求,以及使用编码的用户名和密码发送请求。没有授权标头,我会得到错误:

CORS策略已阻止从原始地址“ http:// localhost:3000”访问“ http:// localhost:8080 / admin”处的XMLHttpRequest:在该服务器上不存在“ Access-Control-Allow-Origin”标头请求的资源。

有了标题,标题中就会出现错误,完整如下:

CORS策略已阻止从来源“ http:// localhost:3000”访问“ http:// localhost:8080 / admin”处的XMLHttpRequest:对预检请求的响应未通过访问控制检查:否'请求的资源上存在Access-Control-Allow-Origin标头。

我已经尝试过针对类似问题提供的多种解决方案,从修改configure方法到向类添加注册表bean不等。不过似乎对我没有任何帮助。还有其他想法吗?

请参阅下面的最新代码: SecurityConfiguration:

@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    MyUserDetailsService userDetailsService;

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors();
        http.authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .antMatchers("/admin").hasRole("ADMIN")
                .antMatchers("/user").hasAnyRole("ADMIN", "USER")
                .antMatchers("/").permitAll()
                .and().formLogin();
    }

    @Bean
    public PasswordEncoder getPasswordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }
}

MyUserDetails:

@Service
public class MyUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
//        Optional<User> user = userRepository.findByUserName(userName);
//
//        user.orElseThrow(() -> new UsernameNotFoundException("Not found: " + userName));
//
//        return user.map(MyUserDetails::new).get();
        User user = new User();
        user.setUserName("John");
        user.setPassword("pass");
        user.setActive(true);
        user.setRoles("ROLE_ADMIN");
        return new MyUserDetails(user);
    }
}

MyUserDetails:

public class MyUserDetails implements UserDetails {

    private String userName;
    private String password;
    private boolean active;
    private List<GrantedAuthority> authorities;

    public MyUserDetails(User user) {
        this.userName = user.getUserName();
        this.password = user.getPassword();
        this.active = user.isActive();
        this.authorities = Arrays.stream(user.getRoles().split(","))
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @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 active;
    }
}

用户:

public class User {
    private int id;
    private String userName;
    private String password;
    private boolean active;
    private String roles;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    public String getRoles() {
        return roles;
    }

    public void setRoles(String roles) {
        this.roles = roles;
    }
}

HomeController:

@CrossOrigin("localhost")
@RestController
public class HomeController {

    @GetMapping("/")
    public String home() {
        return ("<h1>Welcome</h1>");
    }

    @GetMapping("/user")
    public String user() {
        return ("<h1>Welcome User</h1>");
    }

    @GetMapping("/admin")
    public String admin() {
        return ("<h1>Welcome Admin</h1>");
    }
}

最后,我的React组件包括axios请求:

class Demo extends React.Component{
    signIn(){
        axios.get("http://localhost:8080/admin", {
            headers : {
            'Authorization' : 'Basic ' + window.btoa(document.getElementById("username").value + ':' + document.getElementById("password"))
        }}).then(response => {
            console.log(response.data);
            }
        )
    }

    render(){
       return(
           <div>
            {/*<TradeOverview />*/}
            {/*<NewTradeForm />*/}
                <input id="username"/>
                <input id="password" type="password"/>
                <button onClick={this.signIn}>Sign in</button>
           </div>
       ) ;
    }

}

export default Demo;

快速说明:我目前正在对JPA实现进行硬编码,因为这只是一个没有任何数据库的演示。

0 个答案:

没有答案
相关问题