首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Spring安全性:如果用户不满足特定条件,则使每个页面重定向

Spring安全性:如果用户不满足特定条件,则使每个页面重定向
EN

Stack Overflow用户
提问于 2019-06-04 02:06:13
回答 1查看 29关注 0票数 0

我正在开发一个使用Spring Security作为身份验证/授权提供者的web应用程序。下面是我如何配置它:

@Override
protected void configure(HttpSecurity http) throws Exception 
{
    http
        .authorizeRequests()

        //Allow resources for all pages
        .antMatchers("/css/**", "/images/**", "/webjars/**").permitAll()

        //Allow or disallow specific routes depending on user privileges

        //Users
        .antMatchers("/users/", "users/search").hasAuthority("View Users")
        .antMatchers("/users/add", "/users/edit/*", "/users/delete/*").hasAuthority("Edit Users")

        .antMatchers("/roles/", "roles/search").hasAuthority("View Roles")
        .antMatchers("/roles/add", "/roles/edit/*", "/roles/delete/*").hasAuthority("Edit Roles")

        .antMatchers("/permissions/", "permissions/search").hasAuthority("View Permissions")

        //A million other antMatchers here...

        //All custom routes require authentication
        .anyRequest().authenticated()

        //Custom login page and handling
        .and()
            .formLogin()
            .loginPage("/login")
            .loginProcessingUrl("/perform_login")
            .successHandler(loginHandler())
            .failureUrl("/login_error")             
            .permitAll()

        //Custom logout handling with POST request and logout handler for auditing
        .and()
            .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessHandler(logoutHandler())
            .logoutSuccessUrl("/logout_success")
            .permitAll()

        //Invalidate the session and delete the JSESSIONID cookie on logout
        .invalidateHttpSession(true)
        .deleteCookies("JSESSIONID");
}

我不想发布太多的代码(如果需要,我会这样做),但本质上,我的用户存储在一个数据库中,我使用UserDetails和UserDetailsService的一个扩展在Spring Security和DB之间进行交互。在我的用户实体中,我有一个布尔值字段,用于控制用户是否需要更改其密码(首次登录)。为了在用户登录时实现此功能,我有以下AuthenticationSuccessHandler:

    public class LoginHandler implements AuthenticationSuccessHandler
{
    @Autowired
    private UserService userService;

    @Autowired
    private PreferenceService preferenceService;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException 
    {
        User user = userService.findById(((UserDetails) authentication.getPrincipal()).getId());

        if (user.isMustChangePassword())
        {
            response.sendRedirect(request.getContextPath() + "/users/initialPasswordChange");
        }
        else
        {
            response.sendRedirect(request.getContextPath() + getAnchorPageURL(user));
        }
    }
}

这在登录时工作得很好,行为完全符合我的要求。初始密码更改页面没有菜单,但用户可以在不更改其密码的情况下修改URL并登录主页。在旧的Spring MVC时代,我会构建一个在每个页面上运行的自定义过滤器类,它会检查登录的用户是否将该字段设置为true,并重定向到初始密码更改页面。这样,无论用户做什么,在密码更改之前,整个站点都是不可访问的。

现在有没有更优雅的,Spring Security-ey的方式来做到这一点呢?

再一次,我会提供更多的代码,如果可以的话,我不想淹没我的帖子,并希望首先包括最相关的部分。

EN

回答 1

Stack Overflow用户

发布于 2019-06-04 03:29:35

这在旧的Spring MVC过滤器方法中有效。有没有一种更好的,纯Spring Security的方式来做这件事?

@Component
@WebFilter(urlPatterns = {"/*"}, description = "initialPasswordChangeFilter")
public class InitialPasswordChangeFilter implements Filter
{
    @Autowired
    private UserService userService;

    @Override
    public void init(FilterConfig fc) throws ServletException 
    {
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);

        Filter.super.init(fc);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException 
    {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        try
        {
            SecurityContextImpl sci = (SecurityContextImpl) req.getSession(false).getAttribute("SPRING_SECURITY_CONTEXT");

            User user = userService.findById(((UserDetails) sci.getAuthentication().getPrincipal()).getId());

            String url = req.getRequestURL().toString();

            if (user.isMustChangePassword() && !url.contains("initial") && !url.contains("/webjars") && !url.contains("/css") && 
                !url.contains("/js") && !url.contains("/images"))
            {
                res.sendRedirect(req.getContextPath() + "/users/initialPasswordChange");
            }
            else
            {
                chain.doFilter(request, response);
            }
        }
        catch (NullPointerException ex)
        {
            chain.doFilter(request, response);
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56432445

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档