基于与MySql实现用户的认证和授权
实体类
对于要添加进Spring Security上下文的实体类,首先要实现一个接口类UserDetails
具体源码:
public interface UserDetails extends Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}
从上往下依次功能为:
1 根据自定义逻辑来返回用户权限,如果用户权限返回空或者和拦截路径对应权限不同,验证不通过
2返回具体用户密码
3返回具体用户密码
4帐号是否不过期,false则验证不通过
5帐号是否不锁定,false则验证不通过
6凭证是否不过期,false则验证不通过
7该帐号是否启用,false则验证不通过
看一个具体的实体类User:
@Entity
@Table(name = "user1") //设置对应表名字
public class User implements UserDetails{
//主键及自动增长
@Id
@GeneratedValue
private long id;
private String name;
private String password;
//多对多映射,用户角色
@ManyToMany(cascade = {CascadeType.REFRESH},fetch = FetchType.EAGER)
private List<Role> roles;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
//获取当前用户实例的password
@Override
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public User(String name, String password) {
this.name = name;
this.password = password;
}
public User() {
}
//根据自定义逻辑来返回用户权限,如果用户权限返回空或者和拦截路径对应权限不同,验证不通过
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> authorities = new ArrayList<>();
List<Role> roles = this.getRoles();
for (Role role : roles) {
authorities.add(new SimpleGrantedAuthority(role.getRolename()));
}
return authorities;
}
//获取当前用户实例的name
@Override
public String getUsername() {
return this.name;
}
//帐号是否不过期,false则验证不通过
@Override
public boolean isAccountNonExpired() {
return true;
}
//帐号是否不锁定,false则验证不通过
@Override
public boolean isAccountNonLocked() {
return true;
}
//凭证是否不过期,false则验证不通过
@Override
public boolean isCredentialsNonExpired() {
return true;
}
//该帐号是否启用,false则验证不通过
@Override
public boolean isEnabled() {
return true;
}
}
还有角色类实体Role:
@Entity
@Table(name = "role1")
public class Role {
@Id
@GeneratedValue
private long id;
private String rolename;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getRolename() {
return rolename;
}
public void setRolename(String rolename) {
this.rolename = rolename;
}
}
接下来要实现一个类,实现接口类UserDetailsService
看下源码:
public interface UserDetailsService {
//根据用户名定位用户。在实际的实现中,搜索可能是区分大小写的,
或者是区分大小写的,这取决于如何配置实现实例。在本例中,返回的UserDetails对象可能具有与实际请求的不同的用户名。
UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}
它是加载用户特定数据的核心接口。
它在整个框架中作为用户DAO使用,是DaoAuthenticationProvider使用的策略。
该接口只需要一个只读方法,这简化了对新的数据访问策略的支持。
具体实现后的Service类:
public class SecurityService implements UserDetailsService{
//DAO类,帮助实现从数据库查找对应名字的实体类
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = userRepository.findByName(s);
if (user == null) {
throw new UsernameNotFoundException("");
}
return user;
}
}