让我们考虑一个每个人都熟悉的标准身份验证方案。
1. 提示用户使用用户名和密码登录。
2. 系统(成功)验证用户名的密码是否正确。
3. 获取该用户的上下文信息(他们的角色列表等)。
4. 为用户建立安全上下文
5. 用户继续进行,可能执行一些可能受访问控制机制保护的操作,该访问控制机制针对当前安全上下文信息检查操作所需的许可。
前三项构成了身份验证过程,因此我们将了解这些内容是如何在Spring Security中进行的。
1. 获取用户名和密码并将其组合到`UsernamePasswordAuthenticationToken`(`Authentication`接口的实例,我们之前看到)的实例中。
2. token传递给`AuthenticationManager`的实例以进行验证。
3. `AuthenticationManager`在成功验证后返回完全填充的`Authentication`实例。
4. 通过调用`SecurityContextHolder.getContext().setAuthentication(…)`建立安全上下文,传入返回的身份验证对象。
从那时起,用户被认为是经过身份验证的。 我们来看一些代码作为例子。
~~~
import org.springframework.security.authentication.*;
import org.springframework.security.core.*;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
public class AuthenticationExample {
private static AuthenticationManager am = new SampleAuthenticationManager();
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while(true) {
System.out.println("Please enter your username:");
String name = in.readLine();
System.out.println("Please enter your password:");
String password = in.readLine();
try {
Authentication request = new UsernamePasswordAuthenticationToken(name, password);
Authentication result = am.authenticate(request);
SecurityContextHolder.getContext().setAuthentication(result);
break;
} catch(AuthenticationException e) {
System.out.println("Authentication failed: " + e.getMessage());
}
}
System.out.println("Successfully authenticated. Security context contains: " +
SecurityContextHolder.getContext().getAuthentication());
}
}
class SampleAuthenticationManager implements AuthenticationManager {
static final List<GrantedAuthority> AUTHORITIES = new ArrayList<GrantedAuthority>();
static {
AUTHORITIES.add(new SimpleGrantedAuthority("ROLE_USER"));
}
public Authentication authenticate(Authentication auth) throws AuthenticationException {
if (auth.getName().equals(auth.getCredentials())) {
return new UsernamePasswordAuthenticationToken(auth.getName(),
auth.getCredentials(), AUTHORITIES);
}
throw new BadCredentialsException("Bad Credentials");
}
}
~~~
在这里,我们编写了一个小程序,要求用户输入用户名和密码并执行上述顺序。 我们在此实现的AuthenticationManager将验证用户名和密码相同的任何用户。 它为每个用户分配一个角色。 上面的输出将是这样的:
~~~
Please enter your username:
bob
Please enter your password:
password
Authentication failed: Bad Credentials
Please enter your username:
bob
Please enter your password:
bob
Successfully authenticated. Security context contains: \
org.springframework.security.authentication.UsernamePasswordAuthenticationToken@441d0230: \
Principal: bob; Password: [PROTECTED]; \
Authenticated: true; Details: null; \
Granted Authorities: ROLE_USER
~~~
请注意,您通常不需要编写任何类似的代码。 该过程通常在内部进行,例如在Web身份验证过滤器中。 我们刚刚在这里包含了代码,以表明在Spring Security中实际构成身份验证的问题有一个非常简单的答案。 当`SecurityContextHolder`包含完全填充的`Authentication`对象时,用户已进行了身份验证。
- 架构
- 9.技术概述
- 9.1 运行环境
- 9.2 核心组件
- 9.2.1 SecurityContextHolder, SecurityContext and Authentication Objects
- 9.2.2 The UserDetailsService
- 9.2.3 GrantedAuthority
- 9.2.4 总结
- 9.3 验证
- 9.3.1 在Spring Security中验证是什么
- 9.3.2 直接设置SecurityContextHolder内容
- 9.4 web应用中的验证
- 9.4.1 ExceptionTranslationFilter
- 9.4.2 AuthenticationEntryPoint
- 9.4.3 验证机制
- 9.4.4 在请求之间存储SecurityContext
- 9.5 Spring Security中的访问控制(授权)
- 9.5.1 Security and AOP Advice
- 9.5.2 Secure Objects and the AbstractSecurityInterceptor
- 什么是配置属性
- RunAsManager
- AfterInvocationManager
- 扩展安全对象模型
- 9.6 本地化
- 10 核心服务
- 10.1 The AuthenticationManager, ProviderManager and AuthenticationProvider
- 10.1.1 成功验证时擦除凭据
- 10.1.2 DaoAuthenticationProvider
- 10.2 UserDetailsService实现
- 10.2.1 In-Memory Authentication
- 10.2.2 JdbcDaoImpl
- Authority Groups
- 10.3 Password Encoding
- 10.3.1 密码发展史
- 10.3.2 DelegatingPasswordEncoder
- 密码存储格式
- 密码编码
- 密码比对
- 入门体验
- 排除故障
- 10.3.3 BCryptPasswordEncoder
- 10.3.4 Pbkdf2PasswordEncoder
- 10.3.5 SCryptPasswordEncoder
- 10.3.6 其他PasswordEncoders
- 10.4 Jackson的支持
- 11 测试方法安全
- 12 集成spring mvc测试
- 13 webflux支持
- 14 安全过滤器链
- 14.1 DelegatingFilterProxy
- 14.2 FilterChainProxy
- 14.2.1 绕过过滤链
- 14.3 过滤器顺序
- 14.4 匹配请求和http防火墙
- 14.5 与其他基于过滤器的框架一起使用
- 14.6 Advanced Namespace Configuration
- 15. 核心的安全过滤器
- 15.1 FilterSecurityInterceptor
- 15.2 ExceptionTranslationFilter
- 15.3 SecurityContextPersistenceFilter
- 15.4 UsernamePasswordAuthenticationFilter