LoginSignup
32
30

More than 5 years have passed since last update.

Spring Securityを使ってLDAP認証する方法

Last updated at Posted at 2014-11-04

概要

Spring Securityを使った認証で、裏側でLDAPを使って認証させたいときって具体的にどういうコードを書けばいいんだいっていうお話
今回認証はLDAP、権限の管理はDBで行っている。

具体的な話

pom.xml
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-ldap</artifactId>
  <version>3.2.5.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
  <version>1.0.2.RELEASE</version>
</dependency>
LoginController.java
@Controller
public class LoginController {

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String loginInput() {
        return "login";
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login() {
        return "search";
    }

}
  • 権限情報の設定

権限の管理はDBに保存されている情報から取得する。
権限の情報をSpringに渡すにはLdapAuthoritiesPupulatorをimplementsしたクラスを作成する。

DbRoleLdapAuthoritiesPupulator
@Component
public class DbRoleLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator{

    @Autowired
    private UserRepository userRepository;

    @Override
    public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations dirContextOperations, String username) {
        List<GrantedAuthority> authorities = new ArrayList<>();
        User user = userRepository.findByName(username);
        for (Authority auth : Authority.values()) {
            if (auth.getAuthCode() == user.getAuthority()) {
                authorities.add(new SimpleGrantedAuthority(auth.name())); //auth.nameは"ADMIN"とか権限の名前が入る。ROLE_をプレフィックスにするとエラーが出た。
                break;
            }
        }
        return authorities;
    }
  • 認証方法の設定
WebSecurityConfig.java
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authorizeRequests().
                antMatchers("/login").permitAll().anyRequest().authenticated().and().
                formLogin().loginPage("/login").failureUrl("/login").defaultSuccessUrl("/search").and().
                logout().logoutUrl("/logout").permitAll();
    }


    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource("ldap://${ldap_url}:${ldap_port}");
        contextSource.afterPropertiesSet();


        LdapAuthenticationProviderConfigurer<AuthenticationManagerBuilder> configure = auth.ldapAuthentication();

        configure.userDnPatterns("uid={0},ou=fuga,dc=hoge,dc=co,dc=jp").
        contextSource(contextSource).
        ldapAuthoritiesPopulator(dbRoleLdapAuthoritiesPopulator);
    }

}

protected void configure(HttpSecurity http)
このメソッドは認証には関係ない。
ただantMathcers("path").permitAll()しているURL以外(この場合/login以外)にアクセスした時にログインページへ遷移して認証が求められるようになっている。

public void configure(AuthenticationManagerBuilder auth)
認証設定の本命
メソッド内で呼び出されている"ou=fuga,dc=hoge,dc=co,dc=jp"などの引数は各々の環境でのLDAP設定を書いて貰えばいい。
ただ、uid={0}としているところではまった。
ここにはログインの際に入力したユーザ名が入るのだが、ログインフォームのname属性をusernameにしなければならない。そういえばpasswordもname="password"じゃないとダメな気がしてきた。

  • ログインフォーム
login.html
<form class="loginForm" action="/login" method="POST" name="loginForm">
  <!--nameはusername固定-->
  <input name="username" type="text">
  <input name="password" type="password">
  <input type="submit" value="ログイン">
</form>

LDAPの話と直接関係ないけど、Spring Securityを入れるとデフォルトでオンになるBasic認証は以下の設定を書けばオフにできる

application.yml
security:
  basic:
    enabled: false

参考

http://www.slideshare.net/makingx/grails-30-spring-boot
135スライド目からSpring Securityの話

32
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
30