页面重定向取决于使用 Spring 安全性和 Thymeleaf 的角色 - Spring
Posted
技术标签:
【中文标题】页面重定向取决于使用 Spring 安全性和 Thymeleaf 的角色 - Spring【英文标题】:Page redirecting depending on Role using Spring security and Thymeleaf - Spring 【发布时间】:2018-01-24 08:20:06 【问题描述】:我正在使用 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>
【问题讨论】:
【参考方案1】:找到适合我的解决方案。
我将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();
然后我在 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"));
希望对遇到同样问题的人有所帮助。
【讨论】:
如果我们的回答对您有帮助,那么您可以投票给答案。此外,您可以接受哪个对您更有帮助。这是承认他人帮助的方式。谢谢 @sunkuet02 感谢这位朋友!【参考方案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 会自动在request
参数中注入少量HttpServletRequest
属性,使用这个你可以受益。
另一种方式
您可以将控制器方法更改为:
@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
对象。
【讨论】:
我已经熟悉我的用户所拥有的角色。检查我的代码更新。我正在尝试根据他的角色将他重定向到不同的页面。 @sunkuet02 我刚刚对我得到的其他答案写了评论... 我认为我需要使用映射制作单独的控制器,例如“/successLogin”,然后将您在上面编写的逻辑放入其中.如果我用映射“/login”这样写,它永远不会带我进入我的登录页面。你知道怎么做吗? @dome,有login.jsp
页面吗?
你可以在/login
控制器方法中写return "redirect:login.html";
作为返回语句。如果不起作用,请尝试不使用.html
【参考方案3】:
您可以在控制器方法中公开 Spring MVC 将为您注入的 HttpServletRequest
参数,然后使用 HttpServletRequest#isUserInRole(String)。
还假设您已将视图映射如下:
"indexAdmin" -> "/your/static/resource/indexAdmin.html" "indexUser" -> "/your/static/resource/indexUser.html" "indexProfesor" -> "/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 文档链接中所述:
[..]通常用户不应将“ROLE_”前缀传入此 方法[..]
【讨论】:
感谢您的评论。我想我需要使用映射制作单独的控制器,例如“/successLogin”,然后将您在上面编写的逻辑放入其中。如果我用映射“/login”这样写,它永远不会带我进入我的登录页面。你知道怎么做吗?以上是关于页面重定向取决于使用 Spring 安全性和 Thymeleaf 的角色 - Spring的主要内容,如果未能解决你的问题,请参考以下文章
具有 Spring 安全性的 JSF - 登录后重定向到指定页面
Spring 安全性和 Angular javascript 重定向到登录页面
会话超时后,Spring 安全性不会重定向到上次请求的页面登录
Spring Oauth和安全性在登录成功后重定向到/ login