如何在启动时设置默认的@AuthenticationPrincipal

时间:2018-02-05 11:29:25

标签: java spring-boot spring-security

出于开发目的,我正在尝试配置一个development配置文件,开发人员无需在应用程序中对其进行身份验证即可调用REST服务。

但是,其中一些服务需要@AuthenticationPrincipal才能运行。 所以我希望能够在启动时定义一个默认使用的模拟@AuthenticationPrincipal

有没有人有任何想法这样做?

目前,用户身份验证所需的应用程序行为是:

  • 如果用户未经过身份验证,REST端点应发送HTTP代码401。
  • 在这种情况下,前端应该将用户重定向到后端网址/login,以便他可以对自己进行身份验证。
  • 成功后,后端应该将用户重定向到前端。

1 个答案:

答案 0 :(得分:0)

事实证明这不是一个好的解决方案,这里列出了我能想到的不同理由:

  1. 后端服务器的行为在开发环境和生产环境之间会有所不同。
  2. 这会迫使前端在这两种环境之间也有不同的行为。
  3. JUnits无法从端点测试所有预期的答案(例如:如果未经过身份验证,则为HTTP代码401)。
  4. 因此,我已经创建了一个安全配置(仅在不使用生产配置文件时启用),从前端角度模拟预期的行为。

    这里是MockAuthenticationSecurityConfiguration类:

    @Configuration
    @Profile("!PRODUCTION")
    public class MockAuthenticationSecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        private final ApplicationProperties applicationProperties;
    
        public MockAuthenticationSecurityConfiguration(final ApplicationProperties applicationProperties) {
            this.applicationProperties = applicationProperties;
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().antMatchers("swagger-ui.html").permitAll();
            // All API REST endpoint can only be accessed by an authenticated user.
            http.authorizeRequests().antMatchers("/api/**").authenticated()
                    // For these REST endpoint to answer HTTP code 401 in place of redirecting the user to /login.
                    .and().exceptionHandling().defaultAuthenticationEntryPointFor(new Http401UnauthorizedEntryPoint(), new AntPathRequestMatcher("/api/**"))
                    // On success, we want to redirect the user to a specific URL (the frontend).
                    .and().formLogin().permitAll().successHandler(new SimpleUrlAuthenticationSuccessHandler(applicationProperties.getRedirectUrl()))
                    .and().logout().permitAll()
            ;
            http.csrf().disable();
            http.cors();
        }
    
        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            // Add a mocked user to be used to authenticate.
            auth.inMemoryAuthentication().withUser(User.withDefaultPasswordEncoder().username("jdoe").password("jdoe").roles("USER"));
        }
    
    }
    

    这里是Http401UnauthorizedEntryPoint类:

    public class Http401UnauthorizedEntryPoint implements AuthenticationEntryPoint {
    
        @Override
        public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
            response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
        }
    }
    

    然后是ApplicationProperties类:

    @Getter
    @Setter
    @Component
    @ConfigurationProperties("application")
    public class ApplicationProperties {
    
        /**
         * The URL to which we should redirect the user once he is logged in the application.
         */
        private String redirectUrl;
    
    }