'쿠키' 태그의 글 목록 :: 잡다한 프로그래밍
반응형

1. 스프링 시큐리티란?

  • authentication(인증) 과 authorization(권한 부여)를 제어하는 프레임워크
  • De-facto (정해진 표준은 아니지만 사실상 표준)
  • servlet filter를 기반으로함(리퀘스트를 가로채서 선처리하고 리스폰스를 가로채서 후처리함) ex)filter로 UTF-8 인코딩 가능
  • 필터로 등록된 DelegatingFilterProxy가 어떤 URL을 가로챌것인지 정한다


2. 스프링 시큐리티 실습하기 (커스텀 로그인)

 

1) pom.xml에 spring-security dependency 추가하기

<dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>5.2.1.RELEASE</version>
</dependency> 
<dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>5.2.1.RELEASE</version
</dependency> 
<dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>5.2.1.RELEASE</version>
</dependency>

 

2) web.xml에 filter추가

	<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>

 

 

3) security-context.xml 작성

/WEB-INF/spring/appServlet 경로에 security-context.xml을 작성한다. 먼저 name은 text, password는 test1234로 ROLE_USER를 만들고 /secured의 경로로 접근할경우 ROLE_USER인 사람만 접근할 수 있게 설정한다

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:security="http://www.springframework.org/schema/security"
	xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.2.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<security:authentication-manager>
		<security:authentication-provider>
			<security:user-service>
            	<security:user name="test" authorities="ROLE_USER" password="test1234"/>
            </security:user-service>
        </security:authentication-provider>
	</security:authentication-manager>


	<security:http use-expressions="true" auto-config="true">
		<security:intercept-url pattern="/secured/**"
			access="hasRole('ROLE_USER')" />
            
		<security:form-login login-page="/login" />
		<security:logout logout-url="/logout" />
	</security:http>
</beans>

 

4) web.xml 수정

다음과 같이 context-param내부에 security-context.xml경로를 추가한다

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/spring/root-context.xml
			/WEB-INF/spring/appServlet/security-context.xml
		</param-value>
	</context-param>

5) LoginController 작성

@Controller
public class LoginController {

  @RequestMapping(value=“/login”, method = RequestMethod.GET))
  public String login() {

  	return "login";
}

 

5) login.jsp 작성

다음과 같은 login.jsp를 작성한다 csrf 토큰값을 함께 사용하여 csfr공격에 대비한다

<form action="<c:url value="/login" />" method='POST'>

  <table>
    <tr><td>User:</td><td><input type='text' name='username' value=''></td>   </tr>
    <tr><td>Password:</td><td><input type='password' name='password' /></td>  </tr>
    <tr><td colspan='2'><input name="submit" type="submit“ value="Login" /></td> </tr>

    <input type="hidden"  name="${_csrf.parameterName}"value="${_csrf.token}"/>
  </table>

</form>

 

6) 결과

secured로 요청을 보내면 custom login form으로 요청이 전송되고 이를 지정된 ROLE_USER가 맞는지 판단함

 

7) 추가정보

로그인 실패 : /login?error로 요청이 전달됨

로그아웃 성공 : /login?logout으로 요청이 전달됨

따라서 다음과 같이 처리가능

@RequestMapping(value="/login", method = RequestMethod.GET)
public String login(
    @RequestParam(value = "error", required = false) String error, 
    @RequestParam(value="logout", required=false) String logout, 
    Model model) {

    if (error != null) {
        model.addAttribute("errorMsg", "Invalid username and password");
    }

    if(logout != null) {
         model.addAttribute("logoutMsg", "You have been logged out successfully ");
     }

     return "login";

}

 

세션의 시간 설정 및 중복로그인 방지 방법 invalid-session-url = 세션 시간초과

max-sessions = 최대 로그인하는 수, expired-url 중복로그인시 보낼 url

	<security:session-management invalid-session-url="/login?timeout=1">
			<security:concurrency-control max-sessions="1" expired-url="/login" />
		</security:session-management>
반응형
반응형

1. express-session 및 session-store 설치하기

다음과 같이 express-session과 session-file-store를 설치한다. express-session은 세션을 사용하기 위한 미들웨어이고, session-file-store는 session을 파일로 저장하기 위해 사용하는 미들웨어이다. 만약 DB에 저장하려면 다른 미들웨어를 사용하면 된다.

npm install -s express-session

npm install -s session-file-store

2. 설치한 미들웨어 사용하기

다음과 같이 기존 미들웨어 아래에 설치한 미들웨어를 사용하겠다고 선언한다

var session = require('express-session')
var FileStore = require('session-file-store')(session)

 

이후 다음과같은 코드를 추가한다. secret은 사용자가 선택하는 String이 될 수 있으며 이 스트링을 통해 암호화한다. store는 방금 설치한 session-file-store를 통해 파일로 저장하겠다는 의미이다.

app.use(session({
    secret: 'asadlfkj!@#!@#dfgasdg',
    resave: false,
    saveUninitialized: true,
    store: new FileStore()
  }))

3. 세션 스토어를 통한 세션 저장 실습

다음과 같이 사용자가 접속할 경우 session.num을 1로 추가하여 1씩 증가하는 코드이다. 만약 이 코드를 세션 스토어를 사용하지 않고 사용했을 경우에는 node서버를 재시작할 경우 num이 다시 1부터 증가하는 것을 확인할 수 있지만 세션 스토어를 사용할 경우 프로젝트 내부에 session이라는 폴더가 생기고 그 안에 암호화된 세션 파일이 생섬 됨을 확인할 수 있다. 따라서 서버를 재시작하더라도 num이 초기화되지 않는 것을 확인할 수 있다. 이를 이용하면 서버를 재시작하여도 사용자의 로그인이 끊기지 않는다는 등 다양한 구현이 가능해진다.

app.get('/', function (req, res, next) {
    console.log(req.session);
    if(req.session.num === undefined){
        req.session.num = 1;
    } else {
        req.session.num =  req.session.num + 1;
    }
    res.send(`Views : ${req.session.num}`);
})
반응형

+ Recent posts