Authentication
Spring Security can participate in many different authentication environments. While we recommend people use Spring Security for authentication and not integrate with existing Container Managed Authentication, it is nevertheless supported - as is integrating with your own proprietary authentication system.他可以参与不同环境的身份验证环境,但是我们不推荐与你自己的安全环境整合。
What is authentication in Spring Security?
先来看看我们大多数的身份验证场景
1.用户被提示输入用户名和密码登录
2.系统验证了这个用户名的密码是正确的
3.用户获得上下文的信息(比如用户的角色列表等待属性)
4.对这个用户建立安全上下文
5.用户接着会做出一些操作,这些操作会受到潜在的访问控制机制的保护(访问控制机制根据当前用户的安全上下文信息,为当前操作检查所需权限)
前面4项构成了身份验证,我们接下来会看看这些在springsecurity中是如何发生的
1.首先提供的用户名和密码作为参数,合并成一个UsernamePasswordAuthenticationToken对象(他是Authentication接口的实例)
2.为了实现验证,这个token作为参数传递给AuthenticationManager对象
3.在成功的身份验证之后,AuthenticationManager会返回一个带有Authentication的对象
3.通过SecurityContextHolder.getContext().setAuthentication(Authentication对象),传入返回的身份验证对象,这样安全上下文会被生成。
4.这之后,用户就被认为已经被身份验证了
请看例子
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 AUTHORITIES = new ArrayList();
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");
}
}
Setting the SecurityContextHolder Contents Directly
SecurityContextHolder 不关心你如何设置Authentication,它只关心有没有Authentication放进来,该Authentication在AbstractSecurityInterceptor需要授权用户操作之前表示主体。