【问题标题】:How to configure Spring Security for a single page application?如何为单页应用程序配置 Spring Security?
【发布时间】:2015-12-31 03:06:39
【问题描述】:

我遇到了单页应用程序配置 Spring Security 的问题。

所以,默认配置看起来像

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("customUserDetailsService")
    UserDetailsService userDetailsService;

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/", "/list").permitAll()
                .antMatchers("/admin/**").access("hasRole('ADMIN')")
                .and().formLogin().loginPage("/login").permitAll()
                .usernameParameter("ssoId").passwordParameter("password")
                .and().csrf()
                .and().exceptionHandling().accessDeniedPage("/Access_Denied");
    }

    @Bean(name="authenticationManager")
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }


}

从 Login().loginPage("/login") 方法的文档中说它用于重定向到登录页面。对于单页,此配置不相关。 我应该如何为单页应用程序配置 spring?我的意思是如何在控制器和配置文件中配置登录、注销。

【问题讨论】:

  • 您可以查看JHipster 以了解如何使用 Spring 作为后端和 Angular 作为前端来配置登录。

标签: java spring spring-mvc spring-security


【解决方案1】:

Spring Lemon 可以是一个完整的例子,但让我总结一下下面的内容。

默认情况下,当用户成功登录时,Spring Security 会将他重定向到主页。当登录失败或成功注销后,用户将被重定向回登录页面。此外,在尝试访问用户没有足够权限的 URL 时,他会被重定向到登录页面。

正如您所说,这种行为不适合单页应用程序。您的 API 应改为发送 200 响应以及用户数据或 4xx 响应。这可以通过提供您自己的处理程序来完成,如下所示:

@Override
protected void configure(HttpSecurity http) throws Exception {
http
    .formLogin()
        ...
        .successHandler(your authentication success handler object)
        .failureHandler(your authentication failure handler object)
        .and()
    .logout()
        ...
        .logoutSuccessHandler(your logout success handler object)
        .and()
    .exceptionHandling()
        .authenticationEntryPoint(new Http403ForbiddenEntryPoint())
    ...
}

您会在 Internet 上找到许多关于如何编写这些处理程序类的示例。例如,在spring-lemon 项目中,这些代码如下所示。

Authentication Success Handler

@Component
public class AuthenticationSuccessHandler
    extends SimpleUrlAuthenticationSuccessHandler {

    @Autowired    
    private ObjectMapper objectMapper;

    @Autowired    
    private LemonService<?,?> lemonService;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
            HttpServletResponse response,
            Authentication authentication)
    throws IOException, ServletException {

        response.setStatus(HttpServletResponse.SC_OK);
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);

        AbstractUser<?,?> currentUser = lemonService.userForClient();

        response.getOutputStream().print(
                objectMapper.writeValueAsString(currentUser));

        clearAuthenticationAttributes(request);
    }
}

总之,它返回一个 200 响应,响应数据中包含 JSON 化的当前用户。

身份验证失败处理程序

实际上,无需为身份验证失败处理程序编写类 - Spring 提供的SimpleUrlAuthenticationFailureHandler,如果在没有任何参数的情况下进行实例化,则可以按需要工作。

注销成功处理程序

public class LemonLogoutSuccessHandler
    implements LogoutSuccessHandler {

    @Override
    public void onLogoutSuccess(HttpServletRequest request,
        HttpServletResponse response, Authentication authentication)
        throws IOException, ServletException {

          response.setStatus(HttpServletResponse.SC_OK);
    }
}

对于一个详细的例子,参考 Spring Lemon 的LemonWebSecurityConfig 类和它的各个模块的安全包中的其他类可能会有所帮助。

【讨论】:

  • 桑杰,感谢您的解决方案。不幸的是,您列出的处理程序的链接已过时。
  • 哦,是的,之后 SpringLemon 的 master 分支发生了很大变化。我刚刚更新了上面帖子中的链接,但是现在 SpringLemon 是无状态的等等,上面的答案不再是一对一的匹配。
猜你喜欢
  • 2013-10-05
  • 2017-09-26
  • 2012-12-10
  • 2016-08-26
  • 2018-09-03
  • 1970-01-01
相关资源
最近更新 更多