스프링 시큐리티 java config로 설정 변경 하기.
스프링 버전 : 4.0.0.RELEASE
스프링 시큐리티 버전 : 3.2.5.RELEASE
아직 root-context를 xml 설정을 사용하고 있어 시큐리티 부터 java config를 사용하기 위해 시작.
3년전만해도 스프링 시큐리티 문서 진짜 부족한게 많았는데..
이렇게 좋아 지다니.. 놀랍구나.
기존 XML 설정
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd"> <global-method-security pre-post-annotations="enabled" /> <http use-expressions="true" authentication-manager-ref="authManager"> <intercept-url pattern="/index.jsp" access="permitAll" /> <intercept-url pattern="/" access="permitAll" /> <intercept-url pattern="/home" access="permitAll" /> <intercept-url pattern="/favicon.ico" access="permitAll" /> <intercept-url pattern="/resources/**" access="permitAll" /> <intercept-url pattern="/publish/**" access="permitAll" /> <intercept-url pattern="/j_spring_security_logout" access="isAuthenticated()" /> <intercept-url pattern="/user/updateUser" access="isAuthenticated()" /> <intercept-url pattern="/user/info" access="isAuthenticated()" /> <intercept-url pattern="/login/**" access="isAuthenticated()" /> <intercept-url pattern="/gas/**" access="isAuthenticated()" /> <intercept-url pattern="/payment/**" access="isAuthenticated()" /> <intercept-url pattern="/etc/**" access="isAuthenticated()" /> <intercept-url pattern="/stats/**" access="isAuthenticated()" /> <intercept-url pattern="/secure/**" access="isAuthenticated()" /> <intercept-url pattern="/manage/**" access="hasRole('ROLE_ADMIN')" /> <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" /> <intercept-url pattern="/comment/admin/**" access="hasRole('ROLE_ADMIN')" /> <form-login login-page="/user/loginForm" authentication-success-handler-ref="loginSuccessHandler" /> <logout logout-url="/logout" logout-success-url="/home" /> </http> <authentication-manager id="authManager"> <authentication-provider user-service-ref="userDetailService"> <password-encoder ref="passwordEncoder" /> </authentication-provider> </authentication-manager> </beans:beans>
거의 기본 설정이라서 아주 심플하다.
딱히 특별한것도 없음..;
Java Config로 설정
@Configuration @EnableWebSecurity public class SecurityWebApplicationInitializer extends WebSecurityConfigurerAdapter { @Autowired private UserDetailService userDetailService; @Autowired private LoginSuccessHandler loginSuccessHandler; @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/index.jsp", "/home", "/favicon.ico", "/resources/**", "/publish/**").permitAll() .antMatchers("/secure/**", "/manage/**", "/admin/**", "/comment/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin() .loginPage("/user/loginForm") .loginProcessingUrl("/j_spring_security_check") .usernameParameter("j_username") .passwordParameter("j_password") .successHandler(loginSuccessHandler) .permitAll() .and() .logout() .logoutUrl("/logout") .logoutSuccessUrl("/home") .and() .csrf().disable() .httpBasic(); } @Override protected UserDetailsService userDetailsService() { return userDetailService; } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder()); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
위에 링크해둔 스프링 시큐리티 java config 문서에도 친절하게 설명이 잘 나와 있다.
문서 보면서 천천히 해보면 더 좋을 듯.
딱히 특별한건 없고 xml 설정에서 사용하던 authentication-manager를 사용하기 위해서 configre(AuthenticationmanagerBuilder auth)를 세팅했다.
.formLogin() 부분에 보면 processingUrl이랑 username, password 파라미터를 세팅하도록 되어 있는데 이게 원래 기본으로 설정되어 있던거였는데 안되더라..
HttpSecurity.java 의 formLogin()을 보면 FormLoginConfigurer를 사용하는데 여기서 사용하는 default 값이 "username", "password" 이 두가지로 세팅되어 있다.
UsernamePasswordAuthenticationFilter.java 에선 여전히 "j_username", "j_password"를 사용하고 있어서 위처럼 값을 세팅해줘야 사용 가능하다.
그리고 .csrf() 이 설정은 CSRF 공격을 막기위해 세팅되어있는데 .disable()을 세팅해 놓지 않으면 해당 작업을 수행하기 위한 파라미터가 없다고 에러가 발생하기 때문에 .disable()을 해주도록 한다.
csrf().disable()을 안해주면 만나는 에러
HTTP Status 403 - Expected CSRF token not found. Has your session expired?
이렇게 설정을 바꿈으로서 xml 설정보다 코드를 약간 더 줄일 수 있었고, 조금더 읽기 쉬운 코드가 됬다.