【发布时间】:2017-06-03 00:32:23
【问题描述】:
我不太喜欢 Spring Security。我正在开发一个 Spring Boot 项目(实现一些 REST Web 服务),其他人已经实现了 Spring Security 来执行身份验证。它似乎工作正常,但我对它的工作原理(架构)有些怀疑。
所以基本上我有以下课程:
1) User,这是我的模型类,代表一个用户:
@Entity
@Table(name = "user",
uniqueConstraints = {
@UniqueConstraint(columnNames = {"email","username"})
})
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
//@Pattern(regexp="\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b",flags = Pattern.Flag.CASE_INSENSITIVE)
@Column(name="email", unique=true,nullable=false)
private String email;
@NotNull
@Column(name="registration_date",nullable=false)
private Date registration_date;
@NotBlank
@Column(name="username",nullable = false,unique=true)
private String username;
@NotBlank
@Column(name="password",nullable = false)
private String password;
@Column(name="enabled", nullable = false)
private boolean enabled;
@ManyToMany
@JoinTable(name = "user_user_roles", joinColumns = {
@JoinColumn(name = "id_user", updatable = true) },
inverseJoinColumns = { @JoinColumn(name = "id_roles",
updatable = true)},
uniqueConstraints={@UniqueConstraint(columnNames = {"id_user","id_roles"})}
)
@Cascade({CascadeType.DETACH,CascadeType.MERGE,CascadeType.REFRESH,CascadeType.PERSIST,
CascadeType.SAVE_UPDATE})
private List<UserRole> userRoles;
// CONSTRUCTOR, GETTER AND SETTER METHODS
}
它是一个休眠类,它提供与 user_user_roles 数据库表的连接,该数据库表包含与特定用户关联的用户 rool 列表(我认为 ROLE_ADMIN、ROLE_USER等)
2) 然后我有 CustomUserDetails 类扩展 User 并实现 Spring Security UserDetails 接口。
所以这意味着它将包含与特定用户相关的所有信息(其中与该用户关联的角色)并实现 UserDetails 接口中声明的所有方法。
public class CustomUserDetails extends User implements UserDetails {
private static final long serialVersionUID = 1L;
public CustomUserDetails(User user){
super(user);
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
for(UserRole role : this.getUserRoles() ){
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getName());
authorities.add(grantedAuthority);
}
return authorities;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public String getUsername() {
return super.getUsername();
}
}
在我看来,这个类代表了 Spring 应用程序和 Spring Security 之间的桥梁(类似的东西携带与特定用户相关的角色信息,是吗?)。
在此类中,与用户角色列表相关的信息包含在扩展GrantedAuthority的通用对象集合中。
我认为 GrantedAuthority 对象代表用户的角色(实际上是由 role.getName() 构建的,它是代表当前用户角色的字符串)。这个推理对吗?
基本上以前的实现只返回与特定用户相关的GrantedAuthority集合,是吗?
3) CustomUserDetailsService 类实现 Spring Security UserDetailsService 接口:
@Transactional
@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService{
@Autowired
private UserDAO userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userDao.findByUsername(username);
if(user == null){
throw new UsernameNotFoundException("No user present with username: "+username);
}else{
return new CustomUserDetails(user);
}
}
}
基本上这是一个只实现 loadUserByUsername(String username)) 方法的服务:
首先检索与用户相关的信息(User 对象),包括他的角色列表(List userRoles)。
然后使用这个 User 对象构建之前的 CustomUserDetails 用于检索与用户相关的 GrantedAuthority 的集合。
所有这些推理都正确吗?
然后我还有这个 WebSecurityConfig 我认为代表 Spring Security 配置:
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = CustomUserDetailsService.class)
@EnableAutoConfiguration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
}
}
这对我来说很模糊。具体是做什么的?
据我了解,它是通过 ** @EnableWebSecurity** 启用 REST Web 服务安全性。
但是为什么 UserDetailsService bean 的自动装配呢?
这个空的 configure() 方法到底是什么?
【问题讨论】:
标签: java spring spring-mvc spring-boot spring-security