Java 如何在Spring Boot中实现基于角色权限的系统

Java 如何在Spring Boot中实现基于角色权限的系统,java,spring,maven,spring-mvc,spring-security,Java,Spring,Maven,Spring Mvc,Spring Security,我正在尝试使用SpringBoot和SpringSecurity实现基于角色权限的系统。为此,我举了一个例子 ,但未能做到这一点 努力 SpringSecurity配置 package com.insight; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.c

我正在尝试使用SpringBoot和SpringSecurity实现基于角色权限的系统。为此,我举了一个例子 ,但未能做到这一点

努力

SpringSecurity配置

package com.insight;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{

        @Autowired
        private UserDetailsService userDetailsService;

        @Autowired
        private AuthenticationSuccessHandler myAuthenticationSuccessHandler;

        @Autowired
        private LogoutSuccessHandler myLogoutSuccessHandler;

        @Autowired
        private AuthenticationFailureHandler authenticationFailureHandler;

        @Override
        protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(authProvider());
        }

        @Override
        public void configure(final WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/resources/**");
        }

        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            httpSecurity.authorizeRequests()
            .antMatchers("/js/**","/css/**","/images/**","/fonts/**").permitAll()
            .antMatchers("/user/signup/**","/about", "/","/user/login/").permitAll() // #4
            .anyRequest().authenticated() // 7
            .and()
            .formLogin().failureUrl("/user/login?error=true")
            .defaultSuccessUrl("/")
            .loginProcessingUrl("/user/validateLogin")
            .usernameParameter("email")
            .passwordParameter("password")
            .loginPage("/user/login")
            .permitAll()
            .and()
            .logout().logoutRequestMatcher(new AntPathRequestMatcher("/user/logout")).logoutSuccessUrl("/user/login")
            .permitAll();
        }
        @Bean
        public DaoAuthenticationProvider authProvider() {
            final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
            authProvider.setUserDetailsService(userDetailsService);
            authProvider.setPasswordEncoder(encoder());
            return authProvider;
        }

        @Bean
        public PasswordEncoder encoder() {
            return new BCryptPasswordEncoder(11);
        }
    }
用户模型

package com.insight.models;

import java.util.Collection;
import java.util.Date;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Email;

@Entity
@Table(name = "users")
public class User {


     // An autogenerated id (unique for each user in the db)
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;

      @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
      private Set<Address> addresses;

      @NotNull
      @OneToOne(cascade = CascadeType.ALL)
      @JoinColumn(name = "title")
      private Configuration title;

      @OneToOne(cascade=CascadeType.ALL)
        @JoinTable(name="user_roles",
            joinColumns = {@JoinColumn(name="user_id", referencedColumnName="id")},
            inverseJoinColumns = {@JoinColumn(name="role_id", referencedColumnName="id")}
        )
        private Collection<Role> roles;

      @NotNull
      private String firstName;
      @NotNull
      private String lastName;

      @NotNull
      @Column(unique = true)
      @Email
      private String email;
      @NotNull
      private String password;

      private String profileImage;

      @Column(name = "created_at")
      private Date createdAt;
      @Column(name = "created_by")
      private String createdBy;

      @Column(name = "updated_at")
      private Date updatedAt;
      @Column(name = "updated_by")
      private String updatedBy;

      private String status;
      private String deleteFlag;
      private String confirmationCode;
      private String lastLoginAt;
      private boolean enabled;
      private boolean tokenExpired;

      public User() {
            super();
            this.enabled = false;
        }

      @PrePersist
      void createdAt() {
        this.createdAt = this.updatedAt = new Date();
      }

      @PreUpdate
      void updatedAt() {
        this.updatedAt = new Date();
      }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Set<Address> getAddresses() {
        return addresses;
    }

    public void setAddresses(Set<Address> addresses) {
        this.addresses = addresses;
    }

    public Configuration getTitle() {
        return title;
    }

    public void setTitle(Configuration title) {
        this.title = title;
    }



    public Collection<Role> getRoles() {
        return roles;
    }

    public void setRoles(Collection<Role> roles) {
        this.roles = roles;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getProfileImage() {
        return profileImage;
    }

    public void setProfileImage(String profileImage) {
        this.profileImage = profileImage;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    public Date getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }

    public String getUpdatedBy() {
        return updatedBy;
    }

    public void setUpdatedBy(String updatedBy) {
        this.updatedBy = updatedBy;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getDeleteFlag() {
        return deleteFlag;
    }

    public void setDeleteFlag(String deleteFlag) {
        this.deleteFlag = deleteFlag;
    }

    public String getConfirmationCode() {
        return confirmationCode;
    }

    public void setConfirmationCode(String confirmationCode) {
        this.confirmationCode = confirmationCode;
    }

    public String getLastLoginAt() {
        return lastLoginAt;
    }

    public void setLastLoginAt(String lastLoginAt) {
        this.lastLoginAt = lastLoginAt;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public boolean isTokenExpired() {
        return tokenExpired;
    }

    public void setTokenExpired(boolean tokenExpired) {
        this.tokenExpired = tokenExpired;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = (prime * result) + ((email == null) ? 0 : email.hashCode());
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final User user = (User) obj;
        if (!email.equals(user.email)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        final StringBuilder builder = new StringBuilder();
        builder.append("User [firstName=").append(firstName).append("]").append("[lastName=").append(lastName).append("]").append("[username").append(email).append("]");
        return builder.toString();
    }

}
package com.insight.models;

import java.util.Collection;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name="roles")
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    @ManyToMany(mappedBy = "roles")
    private Collection<User> userRoles;

    @ManyToMany
    @JoinTable(
        name = "roles_privileges", 
        joinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"), 
        inverseJoinColumns = @JoinColumn(name = "permission_id", referencedColumnName = "id"))
    private Collection<Permission> permissions;

    public Role(String name) {
        this.name=name;
    }

    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 Collection<User> getUserRoles() {
        return userRoles;
    }

    public void setUserRoles(Collection<User> userRoles) {
        this.userRoles = userRoles;
    }

    public Collection<Permission> getPermissions() {
        return permissions;
    }

    public void setPermissions(Collection<Permission> permissions) {
        this.permissions = permissions;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Role role = (Role) obj;
        if (!role.equals(role.name)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        final StringBuilder builder = new StringBuilder();
        builder.append("Role [name=").append(name).append("]").append("[id=").append(id).append("]");
        return builder.toString();
    }
}
package com.insight.models;

import java.util.Collection;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

public class Permission {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    @ManyToMany(mappedBy = "permissions")
    private Collection<Role> roles;

    public Permission(String name2) {
        name = name;
    }

    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 Collection<Role> getRoles() {
        return roles;
    }

    public void setRoles(Collection<Role> roles) {
        this.roles = roles;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Permission other = (Permission) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    @Override
    public String toString() {
        final StringBuilder builder = new StringBuilder();
        builder.append("Permission [name=").append(name).append("]").append("[id=").append(id).append("]");
        return builder.toString();
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.insight</groupId>
    <artifactId>insight</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>insight</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        </dependency>
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
         </dependency>
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
            <version>1.3.6.RELEASE</version><!--$NO-MVN-MAN-VER$-->
         </dependency>
         <dependency>
            <groupId>org.passay</groupId>
            <artifactId>passay</artifactId>
            <version>1.0</version>
         </dependency>
         <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>19.0</version>
         </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>    
</project>
package com.insight.models;
导入java.util.Collection;
导入java.util.Date;
导入java.util.Set;
导入javax.persistence.CascadeType;
导入javax.persistence.Column;
导入javax.persistence.Entity;
导入javax.persistence.GeneratedValue;
导入javax.persistence.GenerationType;
导入javax.persistence.Id;
导入javax.persistence.JoinColumn;
导入javax.persistence.JoinTable;
导入javax.persistence.OneToMany;
导入javax.persistence.OneToOne;
导入javax.persistence.PrePersist;
导入javax.persistence.PreUpdate;
导入javax.persistence.Table;
导入javax.validation.constraints.NotNull;
导入org.hibernate.validator.constraints.Email;
@实体
@表(name=“users”)
公共类用户{
//自动生成的id(对于数据库中的每个用户都是唯一的)
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
私人长id;
@OneToMany(mappedBy=“user”,cascade=CascadeType.ALL)
专用地址集;
@NotNull
@OneToOne(级联=级联类型.ALL)
@JoinColumn(name=“title”)
私有配置标题;
@OneToOne(级联=级联类型.ALL)
@JoinTable(name=“用户角色”,
joinColumns={@JoinColumn(name=“user\u id”,referencedColumnName=“id”)},
inverseJoinColumns={@JoinColumn(name=“role\u id”,referencedColumnName=“id”)}
)
私人收藏角色;
@NotNull
私有字符串名;
@NotNull
私有字符串lastName;
@NotNull
@列(唯一=真)
@电子邮件
私人字符串电子邮件;
@NotNull
私有字符串密码;
私有字符串轮廓图像;
@列(name=“created_at”)
私人日期创建日期;
@列(name=“创建人”)
创建的私有字符串;
@列(name=“updated_at”)
私人日期更新日期;
@列(name=“更新人”)
私有字符串由更新;
私有字符串状态;
私有字符串删除标志;
私有字符串确认码;
私有字符串lastLoginAt;
启用私有布尔值;
私有布尔标记过期;
公共用户(){
超级();
this.enabled=false;
}
@预科生
void createdAt(){
this.createdAt=this.updatedAt=new Date();
}
@预更新
void updatedAt(){
this.updatedAt=新日期();
}
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
公共集getAddresses(){
返回地址;
}
公共无效设置地址(设置地址){
this.address=地址;
}
公共配置getTitle(){
返回标题;
}
公共无效设置标题(配置标题){
this.title=标题;
}
公共集合getRoles(){
返回角色;
}
公共void集合角色(集合角色){
this.roles=角色;
}
公共字符串getFirstName(){
返回名字;
}
public void setFirstName(字符串firstName){
this.firstName=firstName;
}
公共字符串getLastName(){
返回姓氏;
}
public void setLastName(字符串lastName){
this.lastName=lastName;
}
公共字符串getEmail(){
回复邮件;
}
公用电子邮件(字符串电子邮件){
this.email=电子邮件;
}
公共字符串getPassword(){
返回密码;
}
public void setPassword(字符串密码){
this.password=密码;
}
公共字符串getProfileImage(){
返回图像;
}
public void setProfileImage(字符串profileImage){
this.profileImage=profileImage;
}
公共日期getCreatedAt(){
返回createdAt;
}
公共void setCreatedAt(日期createdAt){
this.createdAt=createdAt;
}
公共字符串getCreatedBy(){
返回createdBy;
}
公共void setCreatedBy(字符串createdBy){
this.createdBy=createdBy;
}
公共日期getUpdatedAt(){
返回更新数据;
}
公共无效设置日期日期(日期更新日期){
this.updatedAt=updatedAt;
}
公共字符串getUpdatedBy(){
返回更新人;
}
public void setUpdatedBy(字符串updatedBy){
this.updatedBy=updatedBy;
}
公共字符串getStatus(){
返回状态;
}
公共无效设置状态(字符串状态){
这个状态=状态;
}
公共字符串getDeleteFlag(){
返回删除标志;
}
公共无效setDeleteFlag(字符串deleteFlag){
this.deleteFlag=deleteFlag;
}
公共字符串getConfirmationCode(){
返回确认码;
}
public void setConfirmationCode(字符串确认码){
this.confirmationCode=确认代码;
}
公共字符串getLastLoginAt(){
返回lastLoginAt;
}
公共void setLastLoginAt(字符串lastLoginAt){
this.lastLoginAt=lastLoginAt;
}
公共布尔值isEnabled(){
返回启用;
}
已启用公共void集(已启用布尔值){
this.enabled=已启用;
}
公共布尔值(){
归还过期的代币;
}
public void setTokenExpired(布尔标记过期){
this.tokenExpired=tokenExpired;
}
@凌驾
公共int hashCode(){
最终整数素数=31;
int结果=1;
结果=(prime*result)+(email==null)?0:email.hashCode();
返回结果;
}
@凌驾
公共布尔等于(最终对象obj){
if(this==obj){
返回true;
package com.insight.services;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
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.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.insight.models.Permission;
import com.insight.models.Role;
import com.insight.models.User;
import com.insight.repositories.RoleRepository;
import com.insight.repositories.UserRepository;



@Service("userDetailsService")
@Transactional
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private IUserService service;
    @Autowired
    private MessageSource messages;
    @Autowired
    private RoleRepository roleRepository;

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        User user = userRepository.findByEmail(email);
        if (user == null) {
            return new org.springframework.security.core.userdetails.User(
              " ", " ", true, true, true, true, 
              getAuthorities(Arrays.asList(roleRepository.findByName("ROLE_USER"))));
        }

        return new org.springframework.security.core.userdetails.User(
          user.getEmail(), user.getPassword(), user.isEnabled(), true, true, 
          true, getAuthorities(user.getRoles()));
    }

    private Collection<? extends GrantedAuthority> getAuthorities(Collection<Role> roles) {
        return getGrantedAuthorities(getPrivileges(roles));
    }

    private List<String> getPrivileges(Collection<Role> roles) {
        List<String> privileges = new ArrayList<String>();
        List<Permission> collection = new ArrayList<Permission>();
        for (Role role : roles) {
            collection.addAll(role.getPermissions());
        }
        for (Permission item : collection) {
            privileges.add(item.getName());
        }
        return privileges;
    }

    private List<GrantedAuthority> getGrantedAuthorities(List<String> privileges) {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        for (String privilege : privileges) {
            authorities.add(new SimpleGrantedAuthority(privilege));
        }
        return authorities;
    }
}
Error creating bean with name 'entityManagerFactory' defined in class path resource[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.200</version>
    <scope>test</scope>
</dependency>