Spring Security 入门
Posted linyukun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Security 入门相关的知识,希望对你有一定的参考价值。
在说完了Spring Security框架的功能和执行流程后,就到了写它Spring Boot的集成,先来看最简的配置:
<parent>
<groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
此时,直接运行程序,页面会跳出都会弹出一个“需要授权”的验证框:
Spring Security会默认生成一个用户,用户名为user,密码可以再IDE的控制台(Console)中查看,输入用户名和密码后就可以访问请求的URL了。
在我们实际的开发中,肯定需要我们定义访问哪些URL需要登录并拥有相关的权限,访问哪些URL不需要登录,以及验证失败后的跳转页面等。配置方式:定义继承WebSecurityConfigurerAdapter 类WebSecurityConfig类,并加上@Configuration 和@EnableWebSecurity两个注解,开启Spring Security功能,并交由容器进行管理。具体配置如下:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
// TODO Auto-generated method stub
http
.authorizeRequests()
//指定任何用户都可以访问‘/‘路径,permitAll()表示任何用户都可以访问
.antMatchers("/").permitAll()
//以"/admin/"开头的URL,只能让"USER"角色权限的用户访问
.antMatchers("/user/**").hasRole("USER")
.and()
//通过formLogin方法登录,并设置登录url为/login,登录成功后跳转/user页面
.formLogin()
.loginPage("/login").defaultSuccessUrl("/user")
.and()
.logout()
//指定登出的url,登出成功后跳转的url路径
.logoutUrl("/logout").logoutSuccessUrl("/login");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
/**
* 在内存中创建一个名为 "user" 的用户,密码为 "pwd",拥有 "USER" 权限,密码使用BCryptPasswordEncoder加密
*/
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("user").password(new BCryptPasswordEncoder().encode("pwd")).roles("USER");
}
/**
* 添加 UserDetailsService, 实现自定义登录校验
*/
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception{
builder.userDetailsService(anyUserDetailsService);
}
}
这是Spring Security进行权限校验管理的一个基本配置啦!
其实看到这里心里还是有很多疑惑:
- 一般用户的信息都是保存在数据库中,那就还要涉及从数据库中读取信息进行验证;
- 登录成功后登录信息保存在哪,保存在SecurityContextHolder中吗?;
- 一般来说还需要自定义用户认证的流程,因为你要从数据库中读取数据,发生错误时需要相关的提示信息;
- 用户登录具体的验证流程是什么样的,该如何重写自定义验证流程?;
这些疑惑网上早就有人想到了,接着看下面的文章。
在知乎和简书上面找到了两张认证流程的图,直观地展示一下:
图一
图二
在Spring Security入门(二)中提到,用户登录时登录信息会封装在Authentication中,然后传递给AuthenticationManager实例进行验证。Authentication是如何在AuthenticationManager实例中进行验证的?具体的流程就如图一所示:
- AuthenticationManager,它是验证管理类的总接口;
- 而具体的验证管理需要ProviderManager类,它具有一个List<AuthenticationProvider> providers属性,这实际上是一个AuthenticationProvider实例构成的验证链;
- 链上都是各种AuthenticationProvider实例,这些实例进行具体的验证工作。
所以根据图二,大致的验证流程如下:
- 后端从前端的表单得到用户密码,包装成一个Authentication类的对象;
- 将Authentication对象传给“验证管理器”ProviderManager进行验证;
- ProviderManager在一条链上依次调用AuthenticationProvider进行验证;
- 其中DaoAuthenticationProvider依赖于UserDetailsService,调用UserDetailsService实例的loadUserByUsername方法,会返回一个UserDetails实例,将UserDetails实例与Authentication对象进行比对;
- 验证成功则返回一个封装了权限信息的Authentication对象(即对象的Collection<? extends GrantedAuthority>属性被赋值);
- 将此对象放入安全上下文SecurityContext中;
- 需要时,可以将Authentication对象从SecurityContextHolder上下文中取出。
还记得上文提到说,用户数据存放于数据库时该如何读取用户信息进行认证吗?没错,就是自定义一个UserDetailsService的类,主要是重写它的loadUserByUsername方法,将用户信息封装在UserDetails对象中。看个具体的栗子:
@Service
public class AnyUserDetailService implements UserDetailsService{
//DAO层的代码省略
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// TODO Auto-generated method stub
User user = userMapper.selectByUsername(username);
if(user == null) {
throw new UsernameNotFoundException("用户不存在!");
}
List<SimpleGrantedAuthority> simpleGrantedAuthorities = createAuthorities(user.getRoles());
return new User(userEntity.getUsername(), userEntity.getPassword(), simpleGrantedAuthorities);
}
自定义了类之后还要配置才能生效,还是在WebSecurityConfig类中进行配置,参见上文。
以上是关于Spring Security 入门的主要内容,如果未能解决你的问题,请参考以下文章
Spring Security OAuth2入门级使用(示例)
Spring Security OAuth2入门级使用(示例)
Spring Security入门(3-7)Spring Security处理页面的ajax请求
Spring Security入门(3-8)Spring Security获取session中的UserDetail