Spring Securityを拡張して「ユーザー名」「パスワード」のほかに「チームID」という文字列を認証処理の要素として追加したいのですが、ログイン後意図したURLに遷移せずに、ルート「"/"」に遷移して404エラーが発生してしまいます。(ログを見た感じだと認証自体は成功しているように見えます。)
一点気になっているのが、WebSecurityConfigクラスにてaddFilter()の記述を除外すると、意図したURLへ遷移します(ログイン中のユーザー情報を取得できずNullPointerExceptionが発生してしまいますが)
とりあえず具体的なログイン処理は後回しにしてDBから「ユーザー名」「パスワード」「チームID」を取得し、それらをそのまま認証情報として受け取り、ログイン成功させる所まで行きたいです。
以下ソースを記載します。(いろいろなサイトを参考にして試行錯誤しているため、読みづらく無駄な部分があるかと思います。。)
長くなってしまい大変恐縮ですが、宜しくお願い致します。
java
1 2@EnableWebSecurity 3@Component 4public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 5 6 private final Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class); 7 8 // 認証 9 @Autowired 10 private UserDaoAuthenticationProvider userDaoAuthenticationProvider; 11 @Autowired 12 private UserDetailsService userDetailsService; 13 14 // 暗号化 15 @Autowired 16 private BCryptPasswordEncoder bCryptPasswordEncoder; 17 18 @Autowired 19 private UserAuthenticationFilter userAuthenticationFilter; 20 21 @Override 22 protected void configure(HttpSecurity httpSecurity) throws Exception { 23 logger.info("WebSecurityConfig configure"); 24 25 httpSecurity.csrf(); 26 27 httpSecurity.authorizeRequests().antMatchers(LoginController.PAGE).permitAll().anyRequest().authenticated().and() 28 .formLogin().loginPage(LoginController.PAGE).successForwardUrl(ProjectManageController.PAGE).defaultSuccessUrl(ProjectManageController.PAGE, false).failureUrl("/error").usernameParameter("user_name").passwordParameter("user_password").permitAll().and().authenticationProvider(userDaoAuthenticationProvider).addFilter(userAuthenticationFilter); 29 // Filter消すとdefaultURL反映される 30 //.formLogin().loginPage(LoginController.PAGE).successForwardUrl(ProjectManageController.PAGE).defaultSuccessUrl(ProjectManageController.PAGE, false).failureUrl("/error").usernameParameter("user_name").passwordParameter("user_password").permitAll().and().authenticationProvider(userDaoAuthenticationProvider); 31 32 33 } 34 35 @Override 36 public void configure(WebSecurity web) throws Exception { 37 web.ignoring().antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/lib/**"); 38 } 39 40 @Autowired 41 public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 42 logger.info("configureGlobal AuthenticationManagerBuilder start"); 43 logger.info(auth.toString()); 44 auth.authenticationProvider(userDaoAuthenticationProvider).userDetailsService(this.userDetailsService).passwordEncoder(bCryptPasswordEncoder); 45 logger.info(auth.getDefaultUserDetailsService().toString()); 46 logger.info("configureGlobal AuthenticationManagerBuilder end"); 47 } 48 49 @Autowired 50 @Override 51 protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception { 52 logger.info("configure AuthenticationManagerBuilder"); 53 authenticationManagerBuilder.authenticationProvider(userDaoAuthenticationProvider).userDetailsService(this.userDetailsService).passwordEncoder(bCryptPasswordEncoder);// 入力値をbcryptでハッシュ化した値でパスワード認証を行うように設定 54 } 55 56 @Autowired 57 public void setUserDetailsService(UserDetailsService userDetailsService) { 58 logger.info("setUserDetailsService"); 59 this.userDetailsService = userDetailsService; 60 } 61} 62
java
1package com.omoumou.gantt.web.login; 2 3 4@Component 5public class UserAuthenticationFilter extends UsernamePasswordAuthenticationFilter { 6 7 private static final Logger logger = LoggerFactory.getLogger(UserAuthenticationFilter.class); 8 9 @Autowired 10 UserMapper userMapper; 11 12 @Autowired 13 private BCryptPasswordEncoder bCryptPasswordEncoder; 14 15 16 // これがないとだめらしい。フィールド形式のAutowiredだとエラーになる 17 @Autowired 18 public void setAuthenticationManager(AuthenticationManager authenticationManager) { 19 super.setAuthenticationManager(authenticationManager); 20 } 21 22 23 @Override 24 public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { 25 logger.info("UserAuthenticationFilter attemptAuthentication"); 26 if (!request.getMethod().equals("POST")) { 27 throw new AuthenticationServiceException("Authentication method not supported: " 28 + request.getMethod()); 29 } 30 31 setUsernameParameter("user_name"); 32 setPasswordParameter("user_password"); 33 String username = super.obtainUsername(request); 34 String password = super.obtainPassword(request); 35 String teamId = obtainTeamId(request); 36 37 38 logger.info("debug001:" + request); 39 logger.info("debug001:" +request.getHeaderNames()); 40 logger.info("debug001:" +request.getLocalAddr()); 41 logger.info("debug001:" + teamId); 42 logger.info("debug001:" + username); 43 logger.info("debug001:" + password); 44 45 46 47 // username required 48 if (!StringUtils.hasText(username)) { 49 logger.info("UserName is required"); 50 throw new AuthenticationServiceException("UserName is required"); 51 } 52 53 LoginUserModel loginUserModel = userMapper.loginUserCheck(username, teamId); 54 55 // 動作確認のためお試し 56 if(loginUserModel != null){ 57 logger.info("debug001: " + loginUserModel.getUserName()); 58 boolean isLoginSsuccess = bCryptPasswordEncoder.matches(password, loginUserModel.getUserPassword()); 59 60 if (!isLoginSsuccess) { 61 logger.info("debug001:パスワードが正しくありません。"); 62 throw new AuthenticationCredentialsNotFoundException("ログイン情報が存在しません。"); 63 }else{ 64 65 logger.info("debug001:パスワードが正しいお"); 66 } 67 } 68 69 70 UserAuthenticationToken authRequest = new UserAuthenticationToken(username, password, teamId); 71 72 // Allow subclasses to set the "details" property 73 setDetails(request, authRequest); 74 75 return this.getAuthenticationManager().authenticate(authRequest); 76 } 77 78 protected String obtainTeamId(HttpServletRequest request) { 79 return request.getParameter("team_id"); 80 } 81}
java
1package com.omoumou.gantt.web.login; 2 3public class UserAuthenticationToken extends UsernamePasswordAuthenticationToken { 4 5 private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; 6 7 private static final Logger logger = LoggerFactory.getLogger(UserAuthenticationToken.class); 8 9 //チームID 10 private final String teamId; 11 12 public UserAuthenticationToken(Object principal, Object credentials, String teamId) { 13 super(principal, credentials); 14 this.teamId = teamId; 15 logger.info("UserAuthenticationToken 1 "); 16 } 17 18 public UserAuthenticationToken(Object principal, Object credentials, String teamId, Collection<? extends GrantedAuthority> authorities) { 19 super(principal, credentials, authorities); 20 this.teamId = teamId; 21 logger.info("UserAuthenticationToken 2 "); 22 } 23 24 public String getTeamId() { 25 return this.teamId; 26 } 27}
java
1package com.omoumou.gantt.web.login; 2 3@Component 4public class UserDaoAuthenticationProvider extends DaoAuthenticationProvider { 5 6 private static final Logger logger = LoggerFactory.getLogger(UserDaoAuthenticationProvider.class); 7 8 @Autowired 9 private UserDetailsService userDetailsService; 10 11 @Autowired 12 UserMapper userMapper; 13 14 @Autowired 15 private BCryptPasswordEncoder bCryptPasswordEncoder; 16 17 18 @Autowired 19 private UserAuthenticationFilter userAuthenticationFilter; 20 21 // TODO: 以下のメソッドをOverrideしないとUserDetails must be setのエラーが発生してしまう。(継承元のクラスでエラーがでいていた) 22 @Override 23 protected void doAfterPropertiesSet() throws Exception { 24 logger.info("doAfterPropertiesSet start"); 25 logger.info("doAfterPropertiesSet userDetailsService: " + userDetailsService.getClass()); 26 } 27 28 @Override 29 public Authentication authenticate(Authentication auth) throws AuthenticationException { 30 31 logger.info("authenticate start"); 32 33 String username = auth.getName(); 34 String password = auth.getCredentials().toString(); 35 logger.info("authenticate username: " + username); 36 logger.info("authenticate password: " + password); 37 logger.info("authenticate end"); 38 39 return new UsernamePasswordAuthenticationToken(auth.getName(), auth.getCredentials(), auth.getAuthorities()); 40 } 41 42 @Override 43 protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException { 44 super.additionalAuthenticationChecks(userDetails, authentication); 45 logger.info("additionalAuthenticationChecks start"); 46 UserAuthenticationToken companyIdUsernamePasswordAuthentication = (UserAuthenticationToken) authentication; 47 String requestedCompanyId = companyIdUsernamePasswordAuthentication.getTeamId(); 48 String companyId = ((LoginUser) userDetails).getUser().getTeamId(); 49 50 if (!companyId.equals(requestedCompanyId)) { 51 throw new BadCredentialsException(messages.getMessage( 52 "AbstractUserDetailsAuthenticationProvider.badCredentials", 53 "Bad credentials")); 54 } 55 } 56 57 @Override 58 protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) { 59 String companyId = ((LoginUser) user).getUser().getTeamId(); 60 return new UserAuthenticationToken(user, authentication.getCredentials(), companyId, user.getAuthorities()); 61 } 62 63 @Override 64 public boolean supports(Class<?> token) { 65 logger.info("supports"); 66 return UsernamePasswordAuthenticationToken.class.isAssignableFrom(token); 67 } 68} 69
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/10/12 13:12
退会済みユーザー
2017/10/12 15:27