【问题标题】:Multiple home pages for different roles in Spring SecuritySpring Security中不同角色的多个主页
【发布时间】:2017-05-18 11:11:08
【问题描述】:

我正在努力让 Spring Boot 应用程序启动并运行安全功能。我在让它运行时遇到了一些困难,因为我已经提出了其他问题。然而,这个问题有点在功能方面。我有多个角色,例如 ADMIN 和 CUSTOMER,登录后我想将它们发送到各自的在线页面。我想出的一种方法是创建一个登录页面,然后使用 cookie 重定向它们,尽管我不知道该怎么做。如果我的方法正确或者 Spring Boot 提供了默认功能,请您提供任何示例,请告诉我。

这是我的 SecurityConfig 类:

package com.crossover.techtrial.java.se.config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private DataSource dataSource;

    @Value("${spring.queries.users-query}")
    private String usersQuery;

    @Value("${spring.queries.roles-query}")
    private String rolesQuery;

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
            throws Exception 
    {
        auth.
            jdbcAuthentication()
                .usersByUsernameQuery(usersQuery)
                .authoritiesByUsernameQuery(rolesQuery)
                .dataSource(dataSource)
                .passwordEncoder(bCryptPasswordEncoder);
    }

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

        http.
            authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/login").permitAll()
                .antMatchers("/registration").permitAll()
                .antMatchers("/app/*").hasAnyAuthority("ADMIN", "CUSTOMER")
                .antMatchers("/admin/**").hasAuthority("ADMIN").anyRequest()                
                .authenticated().and().csrf().disable().formLogin()
                .loginPage("/login").failureUrl("/login?error=true")
                .defaultSuccessUrl("/home")
                .usernameParameter("username")
                .passwordParameter("password")
                .and().logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/").and().exceptionHandling()
                .accessDeniedPage("/access-denied");
    }

    @Override
    public void configure(WebSecurity web) throws Exception 
    {
        web
           .ignoring()
           .antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**");
    }

}

编辑:

正如 dur 所指出的,我可能需要做这样的事情:

public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {


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

    HttpSession session = httpServletRequest.getSession();
    User authUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 
    session.setAttribute("username", authUser.getUsername());        

    //set our response to OK status
    httpServletResponse.setStatus(HttpServletResponse.SC_OK);

    // Now I need to redirect the user based on his role.
    httpServletResponse.sendRedirect("home");
}

}

现在的问题是如何从 authUser 获取角色名称。我希望我做对了,我不需要做任何其他事情。其次,我如何将这个成功的处理程序安装到我的 SecurityConfig 类中。请突出显示需要进行的更改。

【问题讨论】:

    标签: java spring-mvc spring-boot spring-security


    【解决方案1】:

    正如@dur 建议的那样,我通过添加 CustomSuccessHandler 解决了这个问题:

    @Component
    @Configuration
    public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler 
    {
        @Override
        public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
                HttpServletResponse httpServletResponse, Authentication authentication) 
                        throws IOException, ServletException, RuntimeException 
        {
            HttpSession session = httpServletRequest.getSession();
            User authUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            session.setAttribute("username", authUser.getUsername());
            //set our response to OK status
            httpServletResponse.setStatus(HttpServletResponse.SC_OK);
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
            authorities.forEach(authority -> 
                                    { 
                                        if(authority.getAuthority().equals("ADMIN_ROLE")) 
                                        { 
                                            session.setAttribute("role", AppRole.ADMIN);
                                            try
                                            {
                                                //since we have created our custom success handler, its up to us to where
                                                //we will redirect the user after successfully login
                                                httpServletResponse.sendRedirect("/admin/home");
                                            } 
                                            catch (IOException e) 
                                            {
                                                throw new RuntimeException(e);
                                            }                                                                           
                                        }
                                        else if (authority.getAuthority().equals("CUSTOMER_ROLE"))
                                        {
                                            session.setAttribute("role", AppRole.CUSTOMER);
                                            try
                                            {
                                                //since we have created our custom success handler, its up to us to where
                                                //we will redirect the user after successfully login
                                                httpServletResponse.sendRedirect("/user/home");
                                            } 
                                            catch (IOException e) 
                                            {
                                                throw new RuntimeException(e);
                                            }   
                                        }
                                    });
    
        }
    }
    

    我通过配置添加了这个:

    http.
        authorizeRequests()
            .antMatchers("/user/**").hasAuthority("CUSTOMER_ROLE")
            .antMatchers("/admin/**").hasAuthority("ADMIN_ROLE").anyRequest()               
            .authenticated().and().csrf().disable().formLogin()
            .loginPage("/login").failureUrl("/login?error=true")
            .successHandler(successHandler) // successHandler is a reference to my CustomAuthenticationSuccessHandler
            ....
    

    【讨论】:

      【解决方案2】:

      首先尝试从 SecurityContextHolder 获取 SecurityContext (它是 SecurityContext 的持有者)spring 框架保持 Authentication 成功认证后的对象。使用 SecurityContext 你可以得到 Authentication 对象作为 securityContext.getAuthentication() 并且您可以从 Authentication 对象并使用此 Authentication 对象,检查 用户角色并针对不同的用户角色重定向到不同的主页。

      【讨论】:

      • 我们需要在 SecurityConfig 中这样做吗?我该怎么做?
      • 不,您不需要在 SecurityConfig 中执行此操作....只需创建一个实用程序类,您只能从中获取用户角色......并检查您的控制器类中的用户角色.
      猜你喜欢
      • 2014-10-19
      • 2017-12-30
      • 1970-01-01
      • 2015-08-15
      • 2013-01-18
      • 1970-01-01
      • 2019-12-19
      • 2011-08-02
      • 2018-09-22
      相关资源
      最近更新 更多