在这篇 Spring Security 文章中,我想分享有关如何根据经过身份验证的用户在 Java Spring Boot Web 应用程序中的角色重定向经过身份验证的用户的步骤和代码示例。例如,当管理员用户登录时,他将看到“管理仪表板”页面。同样,具有角色编辑器的用户将在成功进行身份验证后看到编辑器仪表板页面。对于具有不同角色的不同用户,依此类推。假设您正在开发一个基于 Spring Boot Web、Spring Data JPA、Hibernate、Spring Security、Thymeleaf 和 MySQL 数据库的 Java Web 应用程序,并且已经实现了用户身份验证和基于角色的授权。
应用程序需要检查当前登录的用户是否具有特定角色。因此,在User实体类中对 hasRole() 方法进行编码,如下所示:如果为用户分配了指定的角色,则hasRole() 方法将返回 true,否则返回 false。并且还要更新您的自定义UserDetails类 – 添加hasRole() 方法,如下所示:Spring Security 将在身份验证成功后返回此UserDetails类的新实例。此类包装了User 的一个实例,因此这里的hasRole() 方法只是将调用委托给User类。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package net.codejava;
import java.util.*;
import javax.persistence.*;
@Entity
@Table(name = "users")
public class User {
@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
@JoinTable(
name = "users_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Setnew HashSet<>();
public boolean hasRole(String roleName) {
Iteratorthis.roles.iterator();
while (iterator.hasNext()) {
Role role = iterator.next();
if (role.getName().equals(roleName)) {
return true;
}
}
return false;
}
// other fields, getters and setters are not shown for brevity
}
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
package net.codejava;
public class CustomUserDetails implements UserDetails {
private User user;
public CustomUserDetails(User user) {
this.user = user;
}
@Override
public Collection extends GrantedAuthority> getAuthorities() {
Set
Listnew ArrayList<>();
for (Role role : roles) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return authorities;
}
public boolean hasRole(String roleName) {
return this.user.hasRole(roleName);
}
// other overriden methods are not shown
}
|
接下来,编写一个扩展AuthenticationSuccessHandler 实现的类,例如SavedRequestAwareAuthenticationSuccessHander,如以下代码:你知道,当用户成功登录时,Spring Security 将调用onAuthenticationSuccess() 方法。因此,将重定向代码放在此方法中是非常合乎逻辑的,以便根据其角色重定向经过身份验证的用户。代码示例是不言自明的,所以我不必进一步解释。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
package net.codejava;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
@Component
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
String redirectURL = request.getContextPath();
if (userDetails.hasRole("Salesperson")) {
redirectURL = "sales_home";
} else if (userDetails.hasRole("Editor")) {
redirectURL = "editor_home";
} else if (userDetails.hasRole("Shipper")) {
redirectURL = "shipper_home";
}
response.sendRedirect(redirectURL);
}
}
|
并更新 Spring 安全性配置类以使用身份验证成功处理程序类,如下所示:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package com.shopme.admin.security;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("email")
.successHandler(loginSuccessHandler)
.permitAll()
.and()
.logout().permitAll();
}
@Autowired private LoginSuccessHandler loginSuccessHandler;
}
|
要了解有关使用身份验证成功处理程序的更多信息,请参阅本文:Spring 安全性身份验证成功处理程序示例。
此部分是可选的。如果基于角色的视图页面(编辑器主页、管理仪表板等)在控制器层中没有相应的处理程序方法,则可以在 Spring MVC 配置中配置视图名称解析,如下所示:这就是如何根据基于 Spring 引导和 Spring 安全性的 Java Web 应用程序中的角色重定向用户的全部内容。希望这篇文章对您有所帮助。要了解实际编码,我建议您观看以下视频:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package net.codejava;
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/sales_home").setViewName("sales_home");
registry.addViewController("/editor_home").setViewName("editor_home");
registry.addViewController("/shipper_home").setViewName("shipper_home");
}
}
|