使用Spring Security、Spring Data Jpa实现的RBAC权限控制

正好这几天不是那么忙,所以就研究了一下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类

  1. User
  2. UserGroup
  3. Role
  4. Permission
  5. Menu
  6. 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
  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 33
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值