https://www.tianmaying.com/tutorial/spring-security
Spring Security,这是一种基于Spring AOP和Servlet过滤器的安全框架。它提供全面的安全性解决方案,同时在Web请求级和方法调用级处理身份确认和授权。在Spring Framework基础上,Spring Security充分利用了依赖注入(DI,Dependency Injection)和面向切面技术。今天我们就来学习一下如何利用Spring security方便的进行权限验证。
添加依赖
首先还是先定义我们所需要的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
在本次学习中,我们仍然使用Spring Boot作为框架,同时引入我们的核心学习库:spring-boot-starter-security
。模板引擎仍然选用我们熟悉的thymeleaf。最后使用了Spring Data Jpa+ hsqldb作为数据库。
系统设计
本次学习,我们将实现一个简单的有权限验证的系统,在权限验证上,我们还可以加上一个简单的用户角色判断的验证,这样,我们就有以下几个页面:
- 首页 所有人可访问
- 登录页 所有人可访问
- 普通页 登录后的用户都可访问
- 管理页 管理员可访问
- 无权限提醒页 当一个用户访问了其没有权限的页面,需要有一个页面来对其进行提醒
页面确定后,我们来看看用户表需要哪些字段。为了简化处理,我们的用户表只需要用户名、密码以及一个角色字段来确定其身份即可。
这样,我们的简单系统设计就出来了,为了加深印象,我们先不管权限验证相关代码,我们先来实现整个简单的系统吧。
系统实现
数据访问层
首先我们需要一个数据层以及业务层为我们的业务逻辑提供支持,由于我们没有业务逻辑,业务逻辑层就省去了,只需要利用Spring Data JPA来实现一个简单数据访问层即可。
首先来定义一个User对象,设置用户名、密码、角色三个字段:
@Entity
public class User {
@Enumerated(EnumType.STRING)
private ROLE role;
@Id
private String username;
private String password;
...
}
然后定义UserRepository:
public interface UserRepository extends JpaRepository<User, Integer> {
User findByUsername(String username);
}
这样,数据访问层就实现好了。
展现层
在展现层,我们需要提供系统设计中的所有页面。基于Spring MVC的Controller
代码如下:
@Controller
public class HomeController {
@RequestMapping(value = {"", "/home"}, method=RequestMethod.GET)
public String home(){
return "home";
}
@RequestMapping(value = "/helloadmin", method=RequestMethod.GET)
public String helloAdmin(){
return "helloAdmin";
}
@RequestMapping(value = "/hellouser", method=RequestMethod.GET)
public String helloUser(){
return "helloUser";
}
@RequestMapping(value = "/login", method=RequestMethod.GET)
public String login(){
return "login";
}
@RequestMapping("/403")
public String forbidden(){
return "403";
}
}
注:其中返回的页面在src/main/resources/templates
下,都是最简单的HTML页面,这里不在赘述。
关于Spring MVC的介绍情参考:Spring MVC快速入门。
大家可以看到,最后一个403页面实际上应该是当用户访问了没有权限的页面后显示的页面,因此在这里我们需要设置:当发现请求的返回码是403
时,需要交给'/403'进行处理。
@Configuration
public class ErrorPageConfig {
@Bean
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
return new MyCustomizer();
}
private static class MyCustomizer implements EmbeddedServletContainerCustomizer {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.addErrorPages(new ErrorPage(HttpStatus.FORBIDDEN, "/403"));
}
}
}
这里我们利用了Spring自带的EmbeddedServletContainerCustomizer进行设置。当Spring发现有类型为EmbeddedServletContainerCustomizer注册进来,便会调用EmbeddedServletContainerCustomizer的customize方法,此时,我们可以对整个Container进行设置,这里,我们添加了对于返回值为HttpStatus.FORBIDDEN
的请求,将其交给/403
进行处理。
启动程序
当然,我们还需要添加一个系统的启动函数,这个大家都应该很熟悉了,没有用过Spring Boot的同学可以参考教材Spring Boot应用开发。
@SpringBootApplication
public class App {
public static void main( String[] args ){
SpringApplication.run(App.class, args);
}
}
初始化数据
最后,让我们准备一些测试数据:
@Service
public class DataInit {
@Autowired UserRepository userRepository;
@PostConstruct
public void dataInit(){
User admin = new User();
admin.setPassword("admin");
admin.setUsername("admin");
admin.setRole(User.ROLE.admin);
userRepository.save(admin);
User user = new User();
user.setPassword("user");
user.setUsername("user");
user.setRole(User.ROLE.user);
userRepository.save(user);
}
}
现在,一切准备就绪,进入根目录,运行mvn spring-boot:run
,访问以下网页即可:
- http://localhost:8080/
- http://localhost:8080/login
- http://localhost:8080/hellouser
- http://localhost:8080/helloadmin
- http://localhost:8080/403
添加权限验证
上节内容我们搭建了一个简单的网页应用,但是其中完全没有任何登录、登出、权限验证等等的处理,只能保证每个页面的简单访问。接下来我们就来用Spring Security添加这些功能。
添加Spring Security配置
我们首先使用Spring Security帮我们做登录、登出的处理,以及当用户未登录时只能访问http://localhost:8080/
以及http://localhost:8080/login
两个页面。
从数据库中获取用户信息的操作是必不可少的,我们首先来实现UserDetailsService,这个接口需要我们实现一个方法:loadUserByUsername
。即通过用户名加载与该用户的用户名、密码以及权限相关的信息。
public class CustomUserDetailsService implements UserDetailsService {
@Autowired UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if(user == null){
throw new UsernameNotFoundException("not found");
}
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority(user.getRole().name()));
System.err.println("username is " + username + ", " + user.getRole().name());
return new org.springframework.security.core.userdetails.User(user.getUsername(),
user.getPassword(), authorities);
}
}
然后我们添加一个SecurityConfig类来对Security进行配置,使AuthenticationManager
使用我们的CustomUserDetailsService
来获取用户信息:
@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
@Bean
public UserDetailsService userDetailsService() {
return new CustomUserDetailsService();
}
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailsService());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/helloadmin")
.permitAll()
.and()
.logout()
.permitAll();
}
}
我们可以看到,SecurityConfig
上添加了@EnableWebMvcSecurity
标注,使得Spring Security提供并且支持了Spring MVC的集成。
同时,SecurityConfig
还继承了WebSecurityConfigurerAdapter
类,并覆盖了其中的几个方法:
- userDetailsService()将我们自定义的
CustomUserDetailsService
实例化并添加进security的上下文当中 - configure(AuthenticationManagerBuilder auth) 在该方法中,我们使AuthenticationManager使用
CustomUserDetailsService
作为其UserDetailsService
实例。 - configure(HttpSecurity http) 对URL进行权限配置,使得"/", "/home"不需要登录就可以访问,其他需要登录。登录的地址是'/login',当登录成功后将跳转到
/helloadmin
页面,并且登录、登出页面都是不需要登录就可以访问的。
这时候重启我们的应用,再次访问http://localhost:8080/hellouser
,你会发现网页会自动跳转到登录页面,同时,我们的登录、登出功能已经实现好了。
实现一个UserDetailsService
,再对Spring Security进行配置,这样,登录、登出以及登录的验证功能就可以实现啦,怎么样,是不是特别的简单。
添加角色验证
之前系统设计时,我们将用户分成了管理员与普通用户,那么,如何将这两类用户访问的页面分开,使得普通用户看不见管理员相关的页面呢?很简单,我们可以通过两行标注来实现这个功能,修改HomeController
:
@RequestMapping(value = "/helloadmin", method=RequestMethod.GET)
@PreAuthorize("hasAnyRole('admin')")
public String helloAdmin(){
return "helloAdmin";
}
@RequestMapping(value = "/hellouser", method=RequestMethod.GET)
@PreAuthorize("hasAnyRole('admin', 'user')")
public String helloUser(){
return "helloUser";
}
修改helloAdmin
和helloUser
方法,添加@PreAuthorize
标注,当我们访问这两个URL的时候,Spring Security会帮我们验证当前用户是否有权限访问该地址。
现在重新启动服务,用user账号登陆,访问'http://localhost:8080/helloadmin',怎么样,是不是看见403页面啦。添加角色控制,就是这么简单。
相关推荐
通过这个"SpringSecurity+MVC入门Demo",初学者可以了解如何在Spring MVC应用中集成Spring Security,实现用户认证和授权的基本流程,为后续深入学习和实践打下基础。这个Demo应该包含了配置文件、控制器、视图和...
在本项目中,我们主要探讨的是如何利用Spring MVC和Spring Security框架构建一个基本的无数据库登录系统。Spring MVC是Spring框架的一部分,用于处理Web应用程序的请求-响应模型,而Spring Security则是一个强大的...
在IT领域,构建一个权限管理系统是企业级应用的常见需求,Spring Security、MyBatis和Spring MVC的整合正是实现这一目标的有效方式。这三个组件分别在不同的层面上为系统提供了强大的支持。 Spring Security是一款...
通过以上步骤,我们可以构建出一个完整的基于Spring Security、MyBatis和Spring MVC的权限管理系统,该系统既具备强大的安全防护,又具有灵活的数据操作和高效的应用架构。这样的系统可以满足大部分企业对权限管理的...
- Spring Security 无缝集成于Spring MVC框架,可以方便地与Spring MVC的其他特性配合使用,如异常处理和模型映射。 10. **Spring Boot集成**: - 在Spring Boot项目中,Spring Security 可以通过自动配置快速...
在这个项目中,这三者协同工作,Spring Security 负责后台的权限控制,Spring MVC 处理业务逻辑和数据交互,而 jQuery Easy-UI 则提供了用户友好的界面。理解这些知识点对于开发和维护这样一个用户权限管理项目至关...
授权:Spring Security提供了细粒度的授权机制,可以根据角色、权限进行访问控制。开发者可以通过配置或编程的方式定义哪些用户可以访问哪些资源。 攻击防护:Spring Security内置了对常见攻击(如跨站点请求伪造、...
1. **身份验证中心(Authentication Server)**:使用Spring Security和Spring OAuth2建立一个独立的授权服务器,处理用户的登录请求,验证用户凭证,并生成访问令牌(Access Token)。 2. **资源服务器(Resource ...
当用户提交登录表单时,Spring Security的过滤器会捕获这个请求,然后调用我们之前配置的AuthenticationProvider进行验证。如果验证成功,用户会被重定向到主页或其他受保护的页面;反之,用户会收到错误消息。 ...
7. **集成Spring MVC**:Spring Security 3.1与Spring MVC无缝集成,可以方便地保护Web控制器和视图。通过注解,如`@Secured`和`@PreAuthorize`,可以在方法级别声明安全约束。 8. **自定义逻辑**:Spring Security...
我们在使用SpringSecurity作为后台权限框架的时候,框架给我们提供了配置登录请求的接口,供我们配置登录链接,当我们配置了登录链接地址后,前端访问登陆请求的时候显示无权限。 异常分析 由于SpringSecurity的...
Spring Security 是一个强大的且高度可定制的身份验证和访问控制框架,用于保护基于Java的应用程序。在Spring Security 3.17版本中,它提供了一套完整的解决方案来处理复杂的权限管理系统,包括用户认证、授权以及...
【标题】"maven+springMVC+spring security权限实例"是一个综合性的IT项目,它展示了如何使用Maven构建一个基于Spring MVC和Spring Security的权限管理应用。这个实例旨在帮助开发者快速理解并实践这三大技术在实际...
这个“Spring Security 权限控制中文API”很可能是对Spring Security框架的中文文档或指南,帮助开发者理解和使用权限控制功能。 Spring Security的核心在于保护资源、进行身份验证(Authentication)和授权...
1. **SpringSecurity架构**:SpringSecurity的核心架构由多个组件构成,包括过滤器链、认证管理、权限控制等。其中,过滤器链是SpringSecurity处理请求的第一道防线,它会拦截所有HTTP请求并进行安全检查。 2. **...
Spring MVC、Spring Security、Thymeleaf 和 Bootstrap 是构建现代Web应用程序的重要技术栈。下面将分别详细介绍这些技术及其在后台管理中的应用。 1. Spring MVC: Spring MVC是Spring框架的一个模块,专门用于...
RBAC是一种权限管理模型,它将用户、角色和权限进行关联,允许管理员为不同角色分配不同的操作权限,提高了系统的安全性。 3. **分布式**:分布式系统是指由多台计算机组成的系统,它们通过网络互相通信,共同完成...
通过这个实例,你可以了解到如何在Spring MVC应用中使用注解简化开发,如何配置和使用Spring Security进行权限控制,以及如何利用Redis优化数据访问和会话管理。这样的实践对于提升个人技能和理解现代企业级应用的...
本项目结合了Freemarker、Spring Security、Spring MVC和Spring Data JPA,旨在实现前端JTable的简单CRUD(创建、读取、更新、删除)功能。以下是这些技术的详细介绍及其在项目中的应用。 **Freemarker** 是一个...
在提供的压缩包`springsecurity配置demo`中,你将找到示例代码和详细说明,这将帮助你更好地理解和实践上述概念。通过学习和实践这些示例,你将能够为自己的Spring应用程序构建强大的安全防护。