読者です 読者をやめる 読者になる 読者になる

SIerだけど技術やりたいブログ

5年目のSIerのブログです

SpringSecurityでEL式を拡張してカスタムルールを作るときのメモ

SpringSecurityでカスタムルールを作る

SpringSecurityで提供されているEL式(hasRole()とか)で足りなくなった場合に、独自のEL式を作成する方法のメモ。

前の記事で作成してたプロジェクトからちょっとカスタマイズして作成。
kimulla.hatenablog.com

カスタムルール用のBeanを作る

コンテナからBeanとして認識されるように作る。

@Component
public class WebSecurity {
  private static int counter;

  /**
   * 2回アクセスがあるごとに一回アクセスを許可するカスタムルール
   */
  public boolean checkMyRule(Authentication auth, HttpServletRequest request) {
    if (auth == null) {
      return false;
    }
    Object principal = auth.getPrincipal();
      if (principal == null) {
        return false;
      } else {
        counter++;
        return (counter % 2 == 0) ? true : false;
      }
  }
}

カスタムルールを使う

重要なのはaccess部分だけ。
@webSecurity.checkMyRule...はSPEL式のBean参照。
引数のauthenticationとrequestはEL式の暗黙オブジェクト?なので、名前までしっかり合わせないといけない。

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity.authorizeRequests()
      // カスタムルールを参照する
      .antMatchers("/admin/**").access("@webSecurity.checkMyRule(authentication,request)")
        .anyRequest().authenticated().and()
      .formLogin()
        .loginPage("/login")
        .defaultSuccessUrl("/home")
        .failureUrl("/login?error")
        .permitAll().and()
      .logout()
        .logoutUrl("/logout")
        .logoutSuccessUrl("/login?logout")
        .permitAll();
  }

宿題

EL式の引数に取れるオブジェクトには、他に何が使えるのかを詳しく調べる。
WebSecurityExpressionRootで定義されてるEL式(パラメータ名は下記リンク)と HttpServletRequest(パラメータ名はrequest)で定義されてるものはアクセス可能っぽい。

http://docs.spring.io/spring-security/site/docs/4.1.0.RC1/reference/htmlsingle/#el-common-built-in



# 参考

リファレンスにすべて載ってた。
http://docs.spring.io/spring-security/site/docs/4.1.0.RC1/reference/htmlsingle/#el-access-web-beans