2015-04-10 17 views
14

zadałem pytanie o ostatni Spring Framework, oparta kod konfiguracji hereWiosna bezpieczeństwa 4 zwyczaj logowanie j_spring_security_check powrotu HTTP 302

initializer

public class AppInitializer extends 
     AbstractAnnotationConfigDispatcherServletInitializer { 

    @Override 
    protected Class<?>[] getRootConfigClasses() { 
     return new Class[] { SecurityConfig.class }; 
    } 

    @Override 
    protected Class<?>[] getServletConfigClasses() { 
     return new Class[] { MvcConfig.class }; 
    } 

    @Override 
    protected String[] getServletMappings() { 
     return new String[] { "/" }; 
    } 
} 

MVC config

@EnableWebMvc 
    @ComponentScan({ "com.appname.controller" }) 
    public class MvcConfig extends WebMvcConfigurerAdapter { 
     @Bean 
     public InternalResourceViewResolver viewResolver() { 
      InternalResourceViewResolver resolver = new InternalResourceViewResolver(); 
      resolver.setPrefix("/WEB-INF/jsp/"); 
      resolver.setSuffix(".jsp"); 
      return resolver; 
     } 

@Override 
    public void addResourceHandlers(ResourceHandlerRegistry registry) { 
     registry.addResourceHandler("/res/**").addResourceLocations("/res/"); 
    } 
    } 

bezpieczeństwo confi g

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true) 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    private CustomUserDetailsService customUserDetailsService; 

public SecurityConfig() { 
    customUserDetailsService = new CustomUserDetailsService(); 
} 

@Autowired 
public void configureGlobal(AuthenticationManagerBuilder auth) 
     throws Exception { 
    auth.inMemoryAuthentication().withUser("user").password("password") 
      .roles("USER"); 
    auth.userDetailsService(customUserDetailsService); 
} 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests() 
      .antMatchers("/res/**").permitAll() 
      .and().authorizeRequests() 
      .anyRequest().hasRole("USER") 
      .and().formLogin().loginPage("/account/signin").permitAll() 
      .and().logout().permitAll(); 
    } 
} 

bezpieczeństwo initializer

public class SecurityInitializer extends 
     AbstractSecurityWebApplicationInitializer { 

} 

zwyczaj logowanie

public class CustomUserDetailsService implements UserDetailsService { 

    private AccountRepository accountRepository; 

    public CustomUserDetailsService() { 
     this.accountRepository = new AccountRepository(); 
    } 

    @Override 
    public UserDetails loadUserByUsername(String email) 
      throws UsernameNotFoundException { 

     Account account = accountRepository.getAccountByEmail(email); 

     if (account == null) { 
      throw new UsernameNotFoundException("Invalid email/password."); 
     } 

     Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 
     authorities.add(new SimpleGrantedAuthority("USER")); 

     return new User(account.getEmail(), account.getPassword(), authorities); 
    } 
} 

Jednak teraz mam nowy problem, o niestandardowym logowania.

podczas postu j_spring_security_check otrzymam HTTP 302.

mam zainteresowanie /, ale po zalogowaniu się pozostaje na stronie logowania.

Ponieważ używam programu Spring Security 4.x i konfiguracji opartej wyłącznie na kodzie, więc nie mogę znaleźć więcej informacji w Internecie. Czy ktoś może pomóc, aby dowiedzieć się, dlaczego.

EDIT

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'securityConfig': 
Injection of autowired dependencies failed; 
nested exception is org.springframework.beans.factory.BeanCreationException: 
Could not autowire field: 
private org.springframework.security.core.userdetails.UserDetailsService sg.mathschool.infra.SecurityConfig.userDetailsService; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [org.springframework.security.core.userdetails.UserDetailsService] found for dependency: 
expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: 
{@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=userDetailsService)} 

Zmieniłem CustomUserDetailsService

@Service("userDetailsService") 
public class CustomUserDetailsService implements UserDetailsService { 

    private AccountRepository accountRepository; 

    public CustomUserDetailsService() { 
     this.accountRepository = new AccountRepository(); 
    } 

    @Override 
    @Transactional(readOnly = true) 
    public UserDetails loadUserByUsername(String email) 
      throws UsernameNotFoundException { 

     Account account = accountRepository.getAccountByEmail(email); 

     if (account == null) { 
      throw new UsernameNotFoundException("Invalid email/password."); 
     } 

     Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 
     authorities.add(new SimpleGrantedAuthority("USER")); 

     return new User(account.getEmail(), account.getPassword(), authorities); 
    } 
} 

i security config

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true) 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    @Qualifier("userDetailsService") 
    private UserDetailsService userDetailsService; 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) 
      throws Exception { 
     auth.inMemoryAuthentication().withUser("user").password("password") 
       .roles("USER"); 
     auth.userDetailsService(userDetailsService).passwordEncoder(
       passwordEncoder()); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests().antMatchers("/res/**").permitAll() 
       .antMatchers("/account/**").permitAll().anyRequest() 
       .hasRole("USER").and().formLogin().loginPage("/account/signin") 
       .failureUrl("/account/signin?error").usernameParameter("email") 
       .passwordParameter("password").and().logout() 
       .logoutSuccessUrl("/account/signin?logout").and().csrf(); 

    } 

    @Bean 
    public PasswordEncoder passwordEncoder() { 
     PasswordEncoder encoder = new BCryptPasswordEncoder(); 
     return encoder; 
    } 
} 
+0

302 jest poprawny, ponieważ j_spring_security_check przekieruje Cię do strony Wellcome. Czego oczekujesz, że powróci? – Nitek

+0

@Nitek, ponieważ żądam /, ale po zalogowaniu pozostaje na stronie logowania. – Timeless

+0

Mam podobny problem, czy wypróbowałeś 'org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler'? Istnieje tam metoda o nazwie 'onAuthenticationSuccess()' tam można wywołać z 'HttpServletResponse' metodę sendRedirect z twoją stroną przekierowania. –

Odpowiedz

1

jest defaultSuccessUrl("/")

formLogin() 
     ... 
     .defaultSuccessUrl("/") 
    ... 
+0

Próbowałem właśnie teraz, nadal nie działa. kiedy próbowałem się zalogować, pozostaje on na stronie logowania. Tak więc próbowałem zażądać /, to będzie reditect, aby zalogować się na stronie. Co oznacza, że ​​uwierzytelnienie gdzieś się nie powiodło. – Timeless

0

Spróbuj również dokładnie określić "loginProcessingUrl":

formLogin() 
    ... 
    .loginProcessingUrl("/j_spring_security_check") 
... 
2

na wiosnę Bezpieczeństwa 4.x logowania URL zmienił się login zamiast j_spring_security_check patrz Migrating from Spring Security 3.x to 4.x (XML Configuration).

<form name='f'action="login" method='POST'> 
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> 
    <table> 
     <tbody> 
      <tr> 
       <td>User Name</td> 
       <td><input type="text" name="username" size="30" /></td> 
      </tr> 
      <tr> 
       <td>Password</td> 
       <td><input type="password" name="password" size="30" /></td> 
      </tr> 
      <tr> 
       <td></td> 
       <td><input type="submit" value="login" /></td> 
      </tr> 
     </tbody> 
    </table> 
</form> 
1

Może to kwestia CORS? cokolwiek to jest, można sprawdzić żądania i odpowiedzi, dodając:

authentication-success-handler-ref="appLoginSuccessHandler" 
authentication-failure-handler-ref="appLoginFailureHandler" 

do zabezpieczenia sprężynowego. to powinno wyglądać następująco:

<http use-expressions="true" disable-url-rewriting="true" > 
    <logout invalidate-session="true" delete-cookies="true"/> 
    <form-login login-page="/YOUR_login_PAGE" 
     username-parameter="j_username" 
     password-parameter="j_password" 
     login-processing-url="/j_spring_security_check" 
     authentication-failure-url="/YOUR_login_PAGE" 
     default-target-url="/YOUR_login_PAGE" 
     authentication-success-handler-ref="appLoginSuccessHandler" 
     authentication-failure-handler-ref="appLoginFailureHandler"/> 

on wezwie odpowiednie metody na usługi appLoginSuccessHandler i appLoginFailureHandler.

Przykład zgłoszenia serwisowego:

@Service("appLoginSuccessHandler") 
public class LoginSuccessHandler extends 
SimpleUrlAuthenticationSuccessHandler{ 

@Override 
public void onAuthenticationSuccess(
HttpServletRequest request, HttpServletResponse response, Authentication 
auth) throws IOException, ServletException{ ...... 
..... 
..... 
..... Here you can handle also CORS ... and more ... 
Powiązane problemy