在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文档非常丰富和出色,这是一个自然的前提感想。

广告
将在 10 秒后关闭
bannerAds