什么是Spring Security中的认证?
让我们考虑每个人都熟悉的标准认证场景。
- 将提示用户使用用户名和密码登录。
- 系统(成功)验证用户名的密码是否正确。
- 获取该用户的上下文信息(它们的角色列表等)。
- 为用户建立安全上下文
- 用户继续潜在地执行可能受到访问控制机制保护的一些操作,访问控制机制检查针对当前安全上下文信息的操作的所需许可。
前三个项目构成了身份验证过程,因此我们将看看Spring Security中如何进行这些操作。
- 获取用户名和密码,并将其组合成一个实例
UsernamePasswordAuthenticationToken
(Authentication
我们之前看到的接口实例)。 - 令牌被传递给验证的实例
AuthenticationManager
。 - 该
AuthenticationManager
收益完全填充Authentication
上验证成功的实例。 - 安全上下文通过调用
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
对象时,将对用户进行身份验证