스프링 시큐리티를 적용해보다가 삽질한 기념으로
정리해서 올려본다…
일단 순서대로 코드를 적용해보면 시큐리티 로그인까지는 적용
메서드별 보안 설정 적용은 추후 알아보도록 하고 일단 기초부터 ^^ 시작
*** 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로 타야되는지 알아볼것.!