首页 文章

Spring Security 禁用登录页面/重定向

提问于
浏览
10

有没有办法禁用 Spring Security 和登录页面的重定向。我的要求指定登录应该是导航菜单的一部分。

例:

在此输入图像描述

因此,没有专用的登录页面。登录信息需要通过 Ajax 提交。如果发生错误,则应返回指定错误的 JSON 并使用正确的 HTTP 状态代码。如果身份验证检出它应该返回 200 然后 javascript 可以从那里处理它。

我希望这是有道理的,除非有更简单的方法来实现 Spring Security。我对 Spring Security 没有多少经验。我认为这必须是一种常见的做法,但我没有找到太多。

当前的弹簧安全配置

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/", "/public/**").permitAll()
                .antMatchers("/about").permitAll()
                .anyRequest().fullyAuthenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .failureUrl("/login?error")
                .usernameParameter("email")
                .permitAll()
                .and()
                .logout()
                .logoutUrl("/logout")
                .deleteCookies("remember-me")
                .logoutSuccessUrl("/")
                .permitAll()
                .and()
                .rememberMe();
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(new BCryptPasswordEncoder());
    }

更新:

我尝试使用 HttpBasic()然后它要求登录信用无关紧要什么及其丑陋的浏览器弹出窗口是最终用户不能接受的。看起来我可能需要扩展 AuthenticationEntryPoint。

在一天结束时,我需要 Spring 安全性发回 JSON,说验证成功或失败。

4 回答

  • 9

    重定向行为来自SavedRequestAwareAuthenticationSuccessHandler 是默认的成功处理程序。因此,删除重定向的简单解决方案是编写自己的成功处理程序。 E.g。

    http.formLogin().successHandler(new AuthenticationSuccessHandler() {
        @Override
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
           //do nothing
        }
    });
    
  • 4

    在我的项目中,我根据要求实现了它:

    1. 如果用户未获得授权,则为 rest-request 401 状态

    2. 如果用户未经授权,则简单页面 302 重定向到登录页面

    public class AccessDeniedFilter extends GenericFilterBean {
    
    @Override
    public void doFilter(
            ServletRequest request,
            ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
    
        try {
            filterChain.doFilter(request, response);
        } catch (Exception e) {
    
            if (e instanceof NestedServletException &&
                    ((NestedServletException) e).getRootCause() instanceof AccessDeniedException) {
    
                HttpServletRequest rq = (HttpServletRequest) request;
                HttpServletResponse rs = (HttpServletResponse) response;
    
                if (isAjax(rq)) {
                    rs.sendError(HttpStatus.FORBIDDEN.value());
                } else {
                    rs.sendRedirect("/#sign-in");
                }
            }
        }
    }
    
    private Boolean isAjax(HttpServletRequest request) {
        return request.getContentType() != null &&
               request.getContentType().contains("application/json") &&
               request.getRequestURI() != null &&
               (request.getRequestURI().contains("api") || request.getRequestURI().contains("rest"));
        }
    }
    

    并启用过滤器:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
       ...
        http
                .addFilterBefore(new AccessDeniedFilter(),
                        FilterSecurityInterceptor.class);
       ...
    }
    

    您可以在条件中为您的需求更改句柄 AccessDeniedException:

    if (isAjax(rq)) {
        rs.sendError(HttpStatus.FORBIDDEN.value());
    } else {
        rs.sendRedirect("/#sign-in");
    }
    
  • 2

    当浏览器获得带有“WWW-Authetication:Basic ...”的 401 时,它会弹出一个 Dialog。除非在请求中看到“X-Requested-With”,否则 Spring Security 会发送该标头。

    您应该为所有请求发送“X-Requested-With:XMLHttpRequest”标头,这是一种老式的说法 - 我是一个 AJAX 请求。

  • -1

    对于基于注释的设置,请使用以下内容:

    .defaultSuccessUrl("/dashboard",true)
    

相关问题