Po namyśle postanowiłem zamienić swoją konfiguracje XML na JavaConfig, lecz oczywiście nie natknąłem się na masę błędów. Wiekszość rozwiązałem, ale z jednym nie mogę sobie poradzić. Posiadam autoryzowane logowanie w JavaConfig
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/loginSuccessfully")
.failureUrl("/login?error=true")
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/logout")
.and()
.csrf();
}
natomiast w XML wyglądało to tak
<http auto-config="true" use-expressions="true">
<form-login login-page="/login" default-target-url="/loginSuccessfully" authentication-failure-url="/login?error=true" username-parameter="username" password-parameter="password" />
<logout logout-success-url="/login" />
<csrf />
</http>
IDENTYCZNIE. Podczas konfiguracji XML działało, a teraz w JavaConfig nie. Natomiast problem polega na tym, że podczas logowania nie jest "używane" Spring Security. Po naciśnięciu na przycisk zaloguj szuka metody oznaczonej 'POST'.
Startowa konfiguracja wygląda tak
@Configuration
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {WebConfig.class,
WebSecurityConfig.class,
WebDatasourceConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
WebConfig(główna konfiguracja łącząca inne konfiguracje)
@Configuration
@EnableWebMvc
@ComponentScan("com.jonki")
@Import({WebSecurityConfig.class, WebDatasourceConfig.class})
public class WebConfig extends WebMvcConfigurerAdapter {
a to cały WebSecurityConfig
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/loginSuccessfully")
.failureUrl("/login?error=true")
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/logout")
.and()
.csrf();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.passwordEncoder(passwordEncoder())
.dataSource(dataSource)
.usersByUsernameQuery("SELECT username, password, enabled FROM users WHERE username=?")
.authoritiesByUsernameQuery("SELECT username, ‘ROLE_USER’ FROM users WHERE username=?");
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
}
Screen https://zapodaj.net/da8c7babc0dad.png.html Gdy na formie logowania naciskam przycisk aby zalogować, to szuka metody oznaczonej PostMapping. A powinno podjąć działanie wg. Spring Security, czyli albo jest poprawne zalogowanie albo błąd. Tak jakby nie widziało tej konfiguracji. Dal sprawdzenia stworzyłem na chwilę metodę PostMapping i wyświetliłem obiekt Principal z SecurityContextHolder i wywaliło NullPointerException(nie stworzyło żadnego obiektu). Czyli wydaje mi się, że te konfiguracje coś się nie stykają.
Klasa WebInit zastępuje stary plik web.xml w którym miałem
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>My application</display-name>
- <servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
- <servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
- <!-- Spring Security
-->
- <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/security-context.xml</param-value>
</context-param>
- <filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
- <filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- <!--
-->
- <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>