正好这几天不是那么忙,所以就研究了一下Spring Security的使用,为了以后方便写篇帖子记录一下。
1.什么是Spring Security?
我想关于什么是Spring Security我都不需要在这里赘述,大家可以到网上百度一下,但是问了大家能快速的融入还是贴一下
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
2.Spring Security有什么?
我们可以使用Spring Security做基于表单的登录认证(form-login)、弹窗的登录认证(http-basic)、对受保护资源的访问控制、单点登录等等。
3.要怎么使用Spring Security?
对于SpringSecurity的登录认证和密码加密等现在都不做讨论,主要说一下对受保护资源的访问控制。
在Spring Security中最做URL权限鉴定最关键的一个类就是FilterSecurityInterceptor,FilterSecurityInterceptor中还需要2个关键的类AccessDecisionManager 和SecurityMetadataSource,这是2个接口类,我们主要的的是他们的实现类。
他们的作用分别是:
AccessDecisionManager做权限的验证
主要方法就是:
void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) ,
SecurityMetadataSource是注入元数据
主要方法是:
public Collection<ConfigAttribute> getAttributes(Object object)
public Collection<ConfigAttribute> getAllConfigAttributes()
开始设计了
主要的domain类
- User
- UserGroup
- Role
- Permission
- Menu
- Resource
这里重点贴一下User.java和Role.java
User.java
package org.ylez.web.domain;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.*;
import java.util.*;
/**
* @FileName: User
* @Author: 唐欢
* @Date: 2016-05-09 22:14
* @Tool: IntelliJ IDEA
*/
@Entity
@Table(name = "t_user")
public class User extends SuperClass implements UserDetails {
@Column(unique = true, nullable = false, length = 30)
private String username;
@Column(nullable = false, length = 30)
private String password;
private int age;
@Column(unique = true)
private String email;
@Column(unique = true, length = 11)
private String phone;
@ManyToMany(targetEntity = UserGroup.class, mappedBy = "users")
private Set<UserGroup> userGroup = new HashSet();
@ManyToMany(targetEntity = Role.class, fetch = FetchType.EAGER)
@JoinTable(name = "m_user_role", joinColumns = {@JoinColumn(name = "user_id")}, inverseJoinColumns = {@JoinColumn(name = "role_id")})
private Set<Role> roles = new HashSet<>();
@Transient
private Set<Role> authorities = new HashSet<>();
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// 包裹用户单独赋予的角色
authorities.addAll(roles);
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Set<UserGroup> getUserGroup() {
return userGroup;
}
public void setUserGroup(Set<UserGroup> userGroup) {
this.userGroup = userGroup;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public void setAuthorities(Set<Role> authorities) {
this.authorities = authorities;
}
}
Role.java
package org.ylez.web.domain;
import org.springframework.security.core.GrantedAuthority;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @FileName: Role
* @Author: 唐欢
* @Date: 2016-05-12 18:15
* @Tool: IntelliJ IDEA
*/
@Entity
@Table(name = "t_role")
public class Role extends SuperClass implements GrantedAuthority {
@Column(nullable = false, length = 30)
private String name;
@Column(nullable = false, length = 30)
private String nickName;
private String comment;
@ManyToMany(targetEntity = Permission.class, fetch = FetchType.EAGER)
@JoinTable(name = "m_role_permission", joinColumns = {@JoinColumn(name = "role_id")}, inverseJoinColumns = {@JoinColumn(name = "permission_id")})
private Set<Permission> permissions = new HashSet<>();
@ManyToMany(targetEntity = User.class, mappedBy = "roles")
private Set<User> users = new HashSet<>();
@ManyToMany(targetEntity = UserGroup.class, mappedBy = "roles")
private Set<UserGroup> userGroups = new HashSet<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public Set<Permission> getPermissions() {
return permissions;
}
public void setPermissions(Set<Permission> permissions) {
this.permissions = permissions;
}
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public Set<UserGroup> getUserGroups() {
return userGroups;
}
public void setUserGroups(Set<UserGroup> userGroups) {
this.userGroups = userGroups;
}
@Override
public String getAuthority() {
return name;
}
}
创建UserDetailsService在登录的时候加载用户信息
package org.ylez.web.security.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.ylez.web.domain.Role;
import org.ylez.web.domain.User;
import org.ylez.web.domain.UserGroup;
import org.ylez.web.service.UserService;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @FileName: UserDetailsServiceImpl
* @Author: 唐欢
* @Date: 2016-05-10 09:39
* @Tool: IntelliJ IDEA
*/
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userService.loadUserByUsername(username);
if (user != null) {
Set<UserGroup> userGroup = user.getUserGroup();
for (UserGroup group : userGroup) {
Set<Role> roles = group.getRoles();
user.setAuthorities(roles);
}
return user;
}else {
throw new UsernameNotFoundException("找不到指定的用户信息!!!");
}
}
}
注意:
for (UserGroup group : userGroup) {
Set<Role> roles = group.getRoles();
user.setAuthorities(roles);
}
这里我讲用户所在的用户组所具有的角色也放置到用的
authorities中
接下类创建一个AuthorizationSecurityInterceptor.java的类源码如下:
package org.ylez.web.security.interceptor;
import java.io.IOException;
import ja