页面重定向取决于使用Spring安全性和Thymeleaf - Spring的角色

时间:2017-08-16 09:03:33

标签: spring spring-boot spring-security thymeleaf

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

SecurityConfig.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();
      } 
}

SecurityWebApplicationInitializer.java

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

}

在我的项目中,我有三个角色:学生,教授和管理员。 我想要实现的是当我的学生登录时,他被重定向到页面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
}

但我没有图片整个控制器应该是什么样子。

让我的homeContorller看起来像这样:

@Controller
public class HomeController {

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

此外,我将此代码添加到我的index.html

<span sec:authorize="isAuthenticated()">
<span sec:authentication="name"></span>
| Roles: <span sec:authentication="principal.authorities"></span> |

所以我熟悉我的登录用户所具有的角色。 这也是我的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>

3 个答案:

答案 0 :(得分:2)

第一种方式

  • 您可以将控制器方法更改为:

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String loginPage(Model model, HttpServletRequest request) {
        if(request.isUserInRole("ROLE_ADMIN") {
             // redirect to indexAdmin.html page
        } else if(request.isUserInRole("ROLE_USER") {
             // redirect indexUser.html page
        } else {
             // redirect to indexProfesor.html page
        }
    }
    

    Spring MVC将自动在HttpServletRequest参数中注入少量request个属性,使用此属性可以使您受益。

另一种方式

  • 您可以将控制器方法更改为:

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String loginPage(Model model, Authentication authentication) {
        if(authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_ADMIN"))) {
            // redirect to indexAdmin.html page
        } else if(authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_USER"))) {
            // redirect indexUser.html page
        } else {
            // redirect to indexProfesor.html page
        }
    }
    

    在这里,Spring MVC会自动将Authentication属性注入authentication对象。

答案 1 :(得分:2)

您可以在控制器方法中公开Spring MVC将为您注入的HttpServletRequest参数,然后使用HttpServletRequest#isUserInRole(String)

还假设您已将视图映射如下:

  • indexAdmin ” - &gt; “/your/static/resource/indexAdmin.html”
  • indexUser ” - &gt; “/your/static/resource/indexUser.html”
  • indexProfesor ” - &gt; “/your/static/resource/indexProfesor.html”

该方法如下所示:

   @Controller
    public class HomeController {

       @RequestMapping(value = "/login", method = RequestMethod.GET)
        public String loginPage(HttpServletRequest httpServletRequest, Model model) {
            if(httpServletRequest.isUserInRole("ADMIN")) {
                return "indexAdmin";
            } else if(httpServletRequest.isUserInRole("USER")) {
                return "indexUser";
            } else {
                return "indexProfesor";
            }
        }
    }

如上面的Spring Documentation链接中所述:

  

[..]通常用户不应将“ROLE_”前缀传入此中   方法[..]

答案 2 :(得分:2)

找到适合我的解决方案。

我在{em> SpringConfig 文件中添加了http.formLogin().defaultSuccessUrl("/success", true)

所以看起来像这样

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();
      }

然后我在 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"));
         }
    }

}

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