在Spring Security(Spring Boot)中,预身份验证
与单一登录基础设施的集成
据说Spring Security还具有与单点登录基础设施集成的功能。虽然有些复杂,但暂时好像是可行的,记下来备忘。
在下面链接的网页中添加功能和修正。
创建一个类
1. 我的预认证过滤器
通过单点登录基础设施等事先嵌入的认证信息(principals, credentials)来提取请求中的认证信息。我们可以通过继承AbstractPreAuthenticatedProcessingFilter来实现这一功能。
2. 我的用户详细信息服务
从提取出的验证信息中,创建用于应用程序的用户信息。扩展AuthenticationUserDetailsService。将其设置为后面要提及的PreAuthenticatedAuthenticationProvider。在这种情况下,AuthenticationUserDetailsService#loadUserDetails方法的参数将是PreAuthenticatedAuthenticationToken,因此需要继承为AuthenticationUserDetailsService。
3. 我的用户权限、我的管理员权限
一般使用者权限和管理员权限类,需要实现GrantedAuthority接口。嗯,虽然权限类的设计有很多种,但是暂且将其创建为不同的类。我认为应该创建一个共同的父类。
大致上的解释流程
-
- PreAuthentifiatedFilterで認証情報を取り出し、フィルタ内の処理で、AuthenticationManagerに認証処理を委譲し、認証結果となるAuthenticationオブジェクトをセッションとスレッドローカルに保存する。(Spring Securityは基本、Authenticationオブジェクトを見て、認証、アクセス制御を行う。)
-
- AuthenticationManagerのデフォルト実装であるProviderManagerは内部のAuthenticationProviderに処理を委譲する。今回は、Spring Securityが提供するPreAuthenticatedAuthenticationProviderをそのまま設定する。
- PreAuthenticatedAuthenticationProvider内部ではreAuthentifiatedFilterで取得された認証情報からAuthenticationUserDetailsServiceを利用して、ユーザー情報を作成しているので、今回はAuthenticationUserDetailsServiceを拡張したクラスを設定する。
有多种用途。
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken>
authenticationUserDetailsService() {
return new MyUserDetailsService();
}
@Bean
public PreAuthenticatedAuthenticationProvider
preAuthenticatedAuthenticationProvider() {
PreAuthenticatedAuthenticationProvider provider
= new PreAuthenticatedAuthenticationProvider();
provider.
setPreAuthenticatedUserDetailsService(authenticationUserDetailsService());
provider.
setUserDetailsChecker(new AccountStatusUserDetailsChecker());
return provider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.authenticationProvider(
preAuthenticatedAuthenticationProvider()
);
}
@Bean
public AbstractPreAuthenticatedProcessingFilter preAuthenticatedProcessingFilter()
throws Exception {
MyPreAuthentifiatedFilter filter = new MyPreAuthenticatedFilter();
filter.setAuthenticationManager(authenticationManager());
return filter;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilter(preAuthenticatedProcessingFilter());
http.authorizeRequests().antMatchers("/", "/home").permitAll()
// 管理者ページの追加
.antMatchers("/admin").hasRole("ADMIN").anyRequest()
.authenticated();
http.formLogin().loginPage("/login").permitAll().and().logout()
.permitAll();
}
}
public class MyPreAuthenticatedFilter extends AbstractPreAuthenticatedProcessingFilter{
@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
//リクエストからユーザーID等のユーザー情報を抽出
return "user01";
}
@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
//リクエストから証明書情報を抽出。DB等にある場合もある?
return "";
}
}
public class MyUserDetailsService implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
@Override
public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token)
throws UsernameNotFoundException {
String userName=(String)token.getPrincipal();
Object credentials = token.getCredentials();
//principalとcredentialsを利用して、ユーザー情報を作成。今回は適当にサンプル作成
Collection<GrantedAuthority> authorities =new HashSet<GrantedAuthority>() ;
authorities.add(new MyAdminAuthority());
User user = new User(userName,"",authorities);
//パスワード渡すとかあり得ないと思うので、別途自分で作成するべき。
return user;
}
}
public class MyAdminAuthority implements GrantedAuthority {
@Override
public String getAuthority() {
return "ROLE_ADMIN";
}
}
public class MyUserAuthority implements GrantedAuthority {
@Override
public String getAuthority() {
return "ROLE_USER";
}
}
查看文件后,不能够准确地知道是否能够按照预期进行动作,所以只能查看源代码。但是,源代码非常易于理解,所以并不太困扰。文件提到了概念、概述和细节需要查看源代码,对于程序员来说是合理的成果物。Spring文档非常丰富和出色,这是一个自然的前提感想。