스프링 시큐리티를 적용해보다가 삽질한 기념으로
정리해서 올려본다…
일단 순서대로 코드를 적용해보면 시큐리티 로그인까지는 적용
메서드별 보안 설정 적용은 추후 알아보도록 하고 일단 기초부터 ^^ 시작
*** pom.xml 추가*** <properties> <org.springframework-security-version>3.1.1.RELEASE</org.springframework-security-version> </properties> <!-- Spring Security --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${org.springframework-security-version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${org.springframework-security-version}</version> </dependency>
*** web.xml 추가 *** <!-- spring security listener--> <listener> <listener-class> org.springframework.security.web.session.HttpSessionEventPublisher </listener-class> </listener> <!-- spring security --> <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>
***spring-security.xml 생성*** ( application-context.xml 같은 위치 or root-context.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" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"]] > <http auto-config="true" ]] > <intercept-url pattern="/login.do" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/login_duplicate.do" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/**" access="ROLE_USER" /> <form-login login-page="/login.do" username-parameter="id" password-parameter="pw" login-processing-url="/loginProcess" default-target-url="/login_success.do" authentication-failure-url="/login_duplicate.do" always-use-default-target="true" /> <!-- login-page : 로그인이 요청될 시에 이동할 URL을 설정합니다. username-parameter : 로그인 아이디의 파라미터명 즉 name필드값을 설정합니다. passoword-parameter : 비밀번호의 파라미터 명을 설정합니다. login-processing-url : 폼에서 전송할 URL 값을 설정합니다. (action=login-processing-url) default-target-url : 사용자 보호된 URL요청시 스프링 시큐리티에서 로그인 페이지를 보여주는 경우 사용자가 로그인 성공 후 대상 URL로 리다이렉트 된다. authentication-failure-url : login 에러시 커스텀 페이지로 이동 (중복 로그인시 해당 url로 이동) always-use-default-target="true" : 로그인 성공후에 default-target-url에 설정한 곳으로 갈지 말지 설정 --> <session-management> <concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/> </session-management> </http> <beans:bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/> <authentication-manager> <authentication-provider ref="CustomAuthenticationProvider"/> </authentication-manager> <beans:bean id="CustomAuthenticationProvider" class="com.demo.test.CustomAuthenticationProvider"/> </beans:beans>
***CustomAuthenticationProvider .java 생성*** (인증 클래스) package com.demo.test; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import daoJava.LogindaoImpl; public class CustomAuthenticationProvider implements AuthenticationProvider { private static final Logger logger = LoggerFactory.getLogger(CustomAuthenticationProvider.class); @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String user_id = (String)authentication.getPrincipal(); String user_pw = (String)authentication.getCredentials(); logger.info("사용자가 입력한 로그인정보입니다. {}", user_id + "/" + user_pw); if(user_id.equals("test")&&user_pw.equals("test")){ logger.info("정상 로그인입니다."); List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>(); roles.add(new SimpleGrantedAuthority("ROLE_USER")); UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(user_id, user_pw, roles); result.setDetails(new LogindaoImpl(user_id, user_pw)); return result; }else{ logger.info("사용자 크리덴셜 정보가 틀립니다. 에러가 발생합니다."); throw new BadCredentialsException("Bad credentials"); } } @RequestMapping(value="/login.do",method=RequestMethod.GET) public String login(){ logger.info("login"); return "layout/login/login"; } }
***LoginController.java 생성*** package com.demo.test; import javax.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import daoJava.LogindaoImpl; @Controller public class LoginController { private static final Logger logger = LoggerFactory.getLogger(LoginController.class); /** * Simply selects the home view to render by returning its name. */ @RequestMapping(value = "/login.do", method = RequestMethod.GET) public void login(HttpSession session) { logger.info("Welcome login! {}", session.getId()); } @RequestMapping(value = "/logout.do", method = RequestMethod.GET) public void logout(HttpSession session) { LogindaoImpl userDetails = (LogindaoImpl) session.getAttribute("userLoginInfo"); logger.info(""+userDetails); logger.info("Welcome logout! {}, {}", session.getId(), userDetails); session.invalidate(); } @RequestMapping(value = "/login_success.do", method = RequestMethod.GET) public void login_success(HttpSession session) { LogindaoImpl userDetails = (LogindaoImpl)SecurityContextHolder.getContext().getAuthentication().getDetails(); logger.info("Welcome login_success! {}, {}", session.getId(), userDetails.getUsername() + "/" + userDetails.getPassword()); session.setAttribute("userLoginInfo", userDetails); } @RequestMapping(value = "page1", method = RequestMethod.GET) public void page1() { } @RequestMapping(value = "/login_duplicate.do", method = RequestMethod.GET) public void login_duplicate() { logger.info("Welcome login_duplicate!"); logger.info("이미 로그인한 id입니다."); } }
*** view Resolver 주의 ***
* spring security로 핸들링 되는 URL은 view Resolver 설정주의
어떤 resolver로 타야되는지 알아볼것.!