使用 Spring security 和 Thymeleaf 根据角色进行页面重定向 - Spring

2 spring spring-security thymeleaf spring-boot

我正在使用 Spring security 和 Thymeleaf 开发我的项目。我有基本的 Spring Security 集成。

安全配置.java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    private DataSource dataSource;

    @Autowired
      public void configureGlobal (AuthenticationManagerBuilder auth) throws Exception
      {
        auth
          .jdbcAuthentication()
            .dataSource(dataSource);
      }

    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
              .antMatchers("/login").permitAll()
              .antMatchers("/classesTable").hasRole("ADMIN")
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")

                .and()
            .httpBasic();
      } 
}
Run Code Online (Sandbox Code Playgroud)

SecurityWebApplicationInitializer.java

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer
{
    public SecurityWebApplicationInitializer(){
        super(SecurityConfig.class);
    }

}
Run Code Online (Sandbox Code Playgroud)

在我的项目中,我扮演三个角色:学生、教授和管理员。我想要实现的是,当我的学生登录时,他被重定向到页面indexUser.html。当我的教授登录时,他会被重定向到indexProfesor.html,而当管理员登录时,他会进入indexAdmin.html页面。

我想到了这样的事情

if(role.contains("ROLE_ADMIN")){
      //redirect from here to indexAdmin.html

    }else if(role.contains("ROLE_USER")) {
        //redirect to indexUser.html
    }else
        //redirect to indexProfesor.html
}
Run Code Online (Sandbox Code Playgroud)

但我不知道整个控制器应该是什么样子。

我的 homeContorller 看起来像这样:

@Controller
public class HomeController {

   @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String loginPage(Model model) {
        return "login";
    }
}
Run Code Online (Sandbox Code Playgroud)

我还将此代码添加到我的index.html中

<span sec:authorize="isAuthenticated()">
<span sec:authentication="name"></span>
| Roles: <span sec:authentication="principal.authorities"></span> |
Run Code Online (Sandbox Code Playgroud)

所以我熟悉我的登录用户所具有的角色。这也是我的 login.html 的代码

<form  th:action="@{/login}" method="post" class="l-form">
  <input type="text" name="username"/>
  <input type="password" name="password"/>
  <input type="hidden" th:name="${_csrf.parameterName}" 
   th:value="${_csrf.token}" />

   <button type="submit" class="btn">Sign in!</button>
</form>
Run Code Online (Sandbox Code Playgroud)

小智 6

找到了适合我的解决方案。

我添加http.formLogin().defaultSuccessUrl("/success", true)到我的SpringConfig文件中。

所以看起来像这样

protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
              .antMatchers("/login").permitAll()
              .antMatchers("/classesTable").hasRole("ADMIN")
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/success", true)
                .and()
            .httpBasic();
      }
Run Code Online (Sandbox Code Playgroud)

然后我在HomeController中创建了一个名为loginPageRedirect的新方法

@Controller
public class HomeController {

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String loginPage(Model model) {
        return "login";
    }
    
    @RequestMapping("/success")
    public void loginPageRedirect(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException, ServletException {
        
        String role =  authResult.getAuthorities().toString();
        
        if(role.contains("ROLE_ADMIN")){
         response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + "/indexAdmin"));                            
         }
         else if(role.contains("ROLE_USER")) {
             response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + "/indexUser"));
         }
    }

}
Run Code Online (Sandbox Code Playgroud)

希望它可以帮助遇到同样问题的人。