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

标签 java spring-boot spring-security

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

但是,其中一些服务需要 @AuthenticationPrincipal 才能工作。 因此,我希望能够在启动时定义默认使用的模拟 @AuthenticationPrincipal

有人有任何想法吗?

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

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

最佳答案

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

  1. 后端服务器的行为在开发环境和生产环境中会有所不同。
  2. 这将迫使前端在这两个环境之间也有不同的行为。
  3. JUnits 无法从端点测试所有预期答案(例如:HTTP 代码 401,如果未经身份验证)。

因此,我创建了一个安全配置(仅在不使用生产配置文件时启用),从前端角度模拟预期行为。

这里是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;

}

关于java - 如何在启动时设置默认@AuthenticationPrincipal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48621622/

相关文章:

Spring Security 3.0.5 自定义过滤器问题

grails - grails 4 sessionRegistry空

java - Spring-Security OpenId 不起作用

java - 使用 Liquibase 和 Git 的推荐工作流程是什么?

java - 如何更改 LiveData 列表的顺序?

java - Mockito + Spring + @PostConstruct,mock初始化错误,为什么调用@PostConstruct?

java - 重构现有模式

java - JsonIninclude 无法防止延迟初始化的 NULL OneToMany 关系的映射异常

java - PDFbox 索引文档中的重叠链接

java - Google OAuth2 JWT token 验证异常