menu
書いてる野郎
orebike@gmail.com
一番簡単なやつ。
まず独自のフィルタを実装する。
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter{ @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { return super.attemptAuthentication(request, response); } }
中身はこのような感じで実装する
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter{ @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { String loginId = request.getParameter("loginId"); String password = request.getParameter("loginPassword"); String hogeKey= request.getParameter("hogeKey"); String hogeKeyLoginId = hogeKey + "##########" + loginId; UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(hogeKeyLoginId, password); this.setDetails(request, token); return this.getAuthenticationManager().authenticate(token); } }
ポイントは、ログインに使うためのパラメータを1個増やしていて(hogeKey)こいつを仕組みの中で使うために username に混ぜ込んで token を作っている。
とりあえずガワ
public class CustomUserDetailsService implements UserDetailsService{ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { return null; } }
この username にさっきパラメータをドッキングさせてきたやつが来るのでそれを処理すればいいということになる。
こんな感じでくっつけたモノを分割して2つのパラメータにすればいい。チェックも入れておこう。
String[] hogeKeyLoginId = StringUtils.split(username, "##########"); if(hogeKeyLoginId == null || hogeKeyLoginId.length != 2) { throw new UsernameNotFoundException("Not OK"); }
次にユーザー情報を取得するのだが、ここは DAO を使って Entity を返したいのだが、 こいつの戻りは UserDetails ではないといけないのでそいつの実装をユーザー情報を司る Entityに入れ込んでやる。
@Entity public class Account implements UserDetails{ // 中略 // このへんに UserDetails の実装をズラズラ書く @Override public Collection<? extends GrantedAuthority> getAuthorities() { Collection<GrantedAuthority> authorityList = new ArrayList<>(); authorityList.add(new SimpleGrantedAuthority(this.getRole().getName())); return authorityList; } @Override public String getUsername() { return this.hogeKey + "##########" + this.loginId; } @Override public boolean isAccountNonExpired() { return false; } @Override public boolean isAccountNonLocked() { return false; } @Override public boolean isCredentialsNonExpired() { return false; } @Override public boolean isEnabled() { return true; } }
出来上がったので DAO を DI してもらって、それで検索するメソッドを使えばよい
最終的にこうなる
public class CustomUserDetailsService implements UserDetailsService{ private AccountDao accountDao; public CustomUserDetailsService(AccountDao accountDao) { this.accountDao = accountDao; } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { String[] hogeKeyLoginId = StringUtils.split(username, "##########"); if(hogeKeyLoginId == null || hogeKeyLoginId.length != 2) { throw new UsernameNotFoundException("Not OK"); } Account account = accountDao.findByLoginIdAndHogeKey(hogeKeyLoginId[1], hogeKeyLoginId[0]); if (account == null) { throw new UsernameNotFoundException("Not OK"); } return account; } }
とりあえずガワ
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter{ @Override public void configure(WebSecurity web) throws Exception { // TODO Auto-generated method stub super.configure(web); } @Override protected void configure(HttpSecurity http) throws Exception { // TODO Auto-generated method stub super.configure(http); } }
静的ファイルは認証不要とする
@Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/img/**", "/css/**", "/js/**"); }