Java 如何在Spring Boot中实现基于角色权限的系统
我正在尝试使用SpringBoot和SpringSecurity实现基于角色权限的系统。为此,我举了一个例子 ,但未能做到这一点 努力 SpringSecurity配置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
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>