当前位置: 首页 > 知识库问答 >
问题:

Spring Security中不同角色的多个主页

邴俊友
2023-03-14

我正在努力让Spring Boot应用程序启动并运行安全功能。我很难让它运行,因为我还提出了其他问题。然而,这个问题有点在功能方面。我有多种角色,如管理员和客户,登录后我想把他们发送到各自的在线页面。我想出的一个办法是创建一个登录页,然后使用cookies重定向它们,尽管我不知道如何做到这一点。如果我的方法是正确的,或者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类相匹配。请强调需要做的更改。

共有2个答案

公冶峰
2023-03-14

首先尝试从SecurityContextHolder(这是SecurityContext的持有者)获取SecurityContext,其中Spring框架在成功身份验证后保留身份验证对象。使用SecurityContext您可以将身份验证对象作为securityContext.get身份验证()并且您可以从身份验证对象中获取用户角色,并使用此身份验证对象,检查用户角色并重定向到不同用户角色的不同主页。

沈成天
2023-03-14

正如@dur所建议的那样,我通过添加一个自定义成功处理程序来解决这个问题:

@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
        ....
 类似资料:
  • 所以С能否请您向我解释一下,正确的方法是否是为不同类型的用户提供不同的DBContext。 例如:我们有两种方法的ApicController: 之后,每个命令都依赖于具有不同配置的不同服务/DbContext。例如: 我觉得我错过了什么或者有更好的解决办法

  • 之后,我连接到master以检查状态: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 名称状态角色年龄版本 在此处输入链接描述 kubectl get Pods-n kube-system 名称就绪状态重新开始时间 库贝-法兰绒-DS-WQFVS 0/1挂起0 7H20M kube-proxy-gmngj 1/1运行2 7H27M kube-

  • 要检查多个角色是否具有方法级访问权限 我已使用@PreAuthorize annotation检查角色 @preAuthorize("hasRole(\""AuthoritiesContain. USER "\",)" ) 如何使用@PreAuthorize注释检查多个角色?

  • 我试图在一个带有spring security和KeyClope的java应用程序中同时使用领域和资源角色。不幸的是,KeyClope只会返回一个或另一个,具体取决于: 您仍然可以通过自定义代码获得这两种方法,但它会弄乱@PreAuthorize或spring boot方法等注释。isUserInRole,这会导致难看的代码。 有没有办法覆盖@PreAuthorize方法或JSON令牌Keyclo

  • 我在libgdx/java使用Box2d的RPG 2d中工作。 我有主角和其他三个追随者。我希望他们像蛇一样沿着主人公的路线走(与Master System/Phantasy Star和其他旧RPG一样),以免在发现狭窄的入口时搞砸。 在我的PlayScreen课程中,我分别调用所有角色。 在屏幕上 HandleInput(浮点dt)方法我只移动主字符 更新(浮点dt)方法 渲染(浮动增量)方法

  • 我在Grails应用程序中集成了Spring security核心插件。