简体   繁体   English

Spring Security:使用@Secured进行安全保护后,找不到剩余端点

[英]Spring Security: Rest endpoint is not found after securing with @Secured

I am trying to secure a REST endpoint via the @Secured annotation of Spring Security. 我正在尝试通过Spring Security的@Secured注释保护REST端点。 My main application (Spring Boot App) with the security config and the rest controller are in different packages and project. 我的主应用程序(带有安全配置的Spring Boot App)和其余控制器位于不同的程序包和项目中。

Main app package: com.myapp.api.web 主应用程序包:com.myapp.api.web

Rest controller packge: com.myapp.api.rest 休息控制器包装:com.myapp.api.rest

Mainapp: Mainapp:

@SpringBootApplication
@ComponentScan(basePackages = "com.myapp.api")
@EntityScan("com.myapp.api")
@RestController
public class ApiApplication extends SpringBootServletInitializer
{
public static void main(String[] args)
{
    SpringApplication.run(ApiApplication.class, args);
}

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
{
    return application.sources(ApiApplication.class);
}

} }

Security Config: 安全配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true, 
securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
private static final String USERS_CONFIG_FILE_NAME = "users.yml";

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http
        .httpBasic()
        .and()
        .csrf().disable();

    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}

@Bean
public PasswordEncoder passwordEncoder()
{
    return new BCryptPasswordEncoder();
}

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth,
    InMemoryUserDetailsManager inMemoryUserDetailsManager, PasswordEncoder passwordEncoder) throws Exception
{
    auth.userDetailsService(inMemoryUserDetailsManager).passwordEncoder(passwordEncoder);
}

@Bean
public InMemoryUserDetailsManager inMemoryUserDetailsManager() throws IOException
{
    return new InMemoryUserDetailsManager(
        PropertiesLoaderUtils.loadAllProperties(USERS_CONFIG_FILE_NAME, getClass().getClassLoader()));
}

} }

Rest controller: 休息控制器:

@RestController
public class RestController
{

private final RestService service;

@PostMapping("/rest/v1")
@Secured({"ROLE_ADMIN"})
public List<String> getStates(@RequestBody List<String> Ids)
{
    ...
}

My rest endpoint is working as long as I am not setting securedEnabled = true . 只要不设置secureEnabled = true,我的其余端点就可以正常工作。 After setting it true I am getting a 404 Not Found as respond message. 设置为true后,我收到404 Not Found作为响应消息。 I've already debugged it and found out that the Spring Security somewhen stops in the filter chain and that the request never reaches the controller. 我已经调试了它,发现Spring Security有时会在过滤器链中停止,并且请求永远不会到达控制器。

As far as I tested it, as long as the rest controller is in a different project this error will occure. 据我测试,只要其余控制器在另一个项目中,就会发生此错误。 After moving it to the same project it is working as it should. 将其移至同一项目后,它应能正常工作。

Is there something missing in my Securityconfig or what could the problem be? 我的Securityconfig中是否缺少某些东西,或者可能是什么问题?

I am able to get values by your code , I have only changed Password Encoder to default and changed inMemoryAuthentication . 我可以通过您的代码获取值,我只将密码编码器更改为默认值,并且将inMemoryAuthentication更改为。 I did it as I don't have your file "users.yml" If you can share a sample , we will look in it , But below is my code. 我这样做是因为我没有您的文件“ users.yml”。如果您可以共享一个示例,我们将在其中进行查找,但是下面是我的代码。 I kept all logic in 2 files just to verify. 我将所有逻辑保存在2个文件中只是为了进行验证。

Configuration Class 配置类别

package com.myapp.api.web.Api;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true, 
securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
private static final String USERS_CONFIG_FILE_NAME = "users.yml";

@Override
protected void configure(HttpSecurity http) throws Exception
{
    http
        .httpBasic()
        .and()
        .csrf().disable();

    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
public PasswordEncoder passwordEncoder() {
    return new PasswordEncoder() {
        @Override
        public String encode(CharSequence rawPassword) {
            return rawPassword.toString();
        }
        @Override
        public boolean matches(CharSequence rawPassword, String encodedPassword) {
            return rawPassword.toString().equals(encodedPassword);
        }
    };
}

@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
    builder.inMemoryAuthentication()
      .withUser("user").password("user").roles("USER")
      .and().withUser("admin").password("admin").roles("ADMIN");
}
/*
@Bean
public InMemoryUserDetailsManager inMemoryUserDetailsManager() throws IOException
{


    return new InMemoryUserDetailsManager(
        PropertiesLoaderUtils.loadAllProperties(USERS_CONFIG_FILE_NAME, getClass().getClassLoader()));
}*/
}

Main Class 主班

package com.myapp.api.web.Api;

import java.util.List;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@ComponentScan(basePackages = "com.myapp.api")
@RestController
@SpringBootApplication
public class ApiApplication {

    public static void main(String[] args) {
        SpringApplication.run(ApiApplication.class, args);
    }
    @PostMapping("/rest/v1")
    @Secured({"ROLE_ADMIN"})
    public List<String> getStates(@RequestBody List<String> Ids)
    {
        return Ids;
       // ...
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM