我正在尝试使用spring boot和spring security实现基于角色权限的系统。为此,我从http://www.baeldung.com/role-and-privilege-for-spring-security-registration举了一个例子。 ,但未能做到这一点。
努力
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();
}
}
的pom.xml
<?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>
CustomUserDetailsService
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;
}
}
还有一些班级,但由于大段,我不发帖,如果有人要求具体,我会发帖。
当我试图运行时,我在控制台上收到以下错误:
org.springframework.beans.factory.BeanCreationException:创建名为'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration'的bean时出错:注入自动连接的依赖项失败;嵌套异常是org.springframework.beans.factory.BeanCreationException:无法自动装配方法:public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.springframework.security.config.annotation.ObjectPostProcessor, java.util.List)抛出java.lang.Exception;嵌套异常是org.springframework.beans.factory.BeanExpressionException:表达式解析失败;嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为'securityConfiguration'的bean时出错:注入自动连接的依赖项失败;嵌套异常是org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private org.springframework.security.core.userdetails.UserDetailsService com.insight.SecurityConfiguration.userDetailsService;嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为'userDetailsService'的bean时出错:注入自动连接的依赖项失败;嵌套异常是org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private com.insight.repositories.UserRepository com.insight.services.CustomUserDetailsService.userRepository;嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为'userRepository'的bean时出错:在设置bean时无法创建[org.springframework.orm.jpa.SharedEntityManagerCreator]类型的内部bean'(内部bean)#778bd3a2' property'entalManager';嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为'(内部bean)#778bd3a2'的bean时出错:在设置构造函数参数时无法解析对bean'entalManagerFactory'的引用;嵌套异常是org.springframework.beans.factory.BeanCreationException:在类路径资源中定义名为'entityManagerFactory'的bean时出错[org / springframework / boot / autoconfigure / orm / jpa / HibernateJpaAutoConfiguration.class]:init方法的调用失败;嵌套异常是javax.persistence.PersistenceException:[PersistenceUnit:default]无法构建Hibernate SessionFactory 在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:306)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:368)〜[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在
请朋友们帮帮我。
答案 0 :(得分:0)
正如Michal所指出的,这是一个数据库问题-
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)
您的MySQL数据库可能未运行,或者您可能未在spring属性中提供数据源连接[我看到您有一个MySQL依赖项引用]
对于调试或测试用例,您可以尝试使用H2-
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
<scope>test</scope>
</dependency>
答案 1 :(得分:-2)
使用SecurityConfiguration
@EnableWebSecurity
添加注释