Spring Security 单项目权限设计过程解析
在一个Web应用中,权限管理一般是必不可少的功能。Spring Security 提供了强大的组件和方法,使得我们可以轻松地在应用中添加认证和授权的功能。针对单个应用的权限管理,一般需要经过以下步骤:
步骤一:添加依赖
在项目的 pom.xml
文件中,我们需要添加以下依赖:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>5.5.0</version>
</dependency>
步骤二:配置安全框架
在Spring Security中,我们需要定义一个配置类,来配置安全框架的一些组件和选项。一个基于Java配置的Spring Security配置类如下:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}
在这个配置类中,我们:
- 使用
@Configuration
注解来标记这个类是一个配置类。 - 使用
@EnableWebSecurity
注解来启用 Spring Security。 - 注入一个实现了
UserDetailsService
接口的对象,用于载入用户的认证信息。 - 定义了一个
PasswordEncoder
的 Bean,用于加密密码。 - 重写了
configure(HttpSecurity http)
方法,来定义我们的安全策略。 - 重写了
configureGlobal(AuthenticationManagerBuilder auth)
方法,来配置我们的认证管理器。
在上述代码中,我们定义了以下安全策略:
/
和/home
都是允许匿名访问的。/admin/**
下的所有资源都需要具有ROLE_ADMIN
权限的用户才能访问。- 其他所有资源都需要登录后访问。
- 定义了一个登录页面为
/login
。 - 开启了记住我功能。
- 定义了一个登出页面为
/logout
。
步骤三:定义用户信息
我们需要定义一些用户信息来使我们的应用可以进行认证和授权。我们可以通过实现 UserDetails
接口并创建一个用户类来完成该任务。例如:
public class User implements UserDetails {
private String username;
private String password;
private boolean enabled;
private Set<Role> roles;
// getters and setters
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> authorities = new HashSet<>();
for (Role role : roles) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return authorities;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
}
在这个例子中,User
类实现了 UserDetails
接口,它的字段 username
,password
,和 enabled
对应了一个用户的基本信息,roles
属性则是用户的角色列表。
示例一
以下是一个使用 WebSecurityConfig
和 User
类的示例:
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebMvcConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}
User 类:
public class User implements UserDetails {
private String username;
private String password;
private boolean enabled;
private Set<Role> roles;
// getters and setters
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> authorities = new HashSet<>();
for (Role role : roles) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return authorities;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isEnabled() {
return enabled;
}
}
我们可以使用这个配置类和 User
类来完成一个基础的角色管理系统。
示例二
下面是另一个使用 @PreAuthorize
注解来限制访问的示例:
@PreAuthorize("hasRole('ROLE_USER')")
@RequestMapping("/myaccount")
public String myaccount() {
return "myaccount";
}
在这个例子中,@PreAuthorize("hasRole('ROLE_USER')")
注解表示只有具有 ROLE_USER
权限的用户才能访问 /myaccount
请求处理方法。
通过以上示例,我们就可以对Spring Security单项目权限设计过程进行完整的攻略了。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security单项目权限设计过程解析 - Python技术站