<스프링 시큐리티 적용시>


web.xml



<!-- 파일업로드 필터 -->
<filter>
    <filter-name>springMultipartFilter</filter-name>
    <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>springMultipartFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 스프링 시큐리티 필터 -->
<!-- 스프링 시큐리티 필터는 파일업로드 필터 앞에 나오면 안됨-->
<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>
cs



Servers의 content.xml



<Content>
<!-- 밑에꺼로 변경 --> 
<Context allowCasualMultipartParsing="true">
cs



<파일 용량 에러>


Servers의 server.xml


1
2
3
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
<!-- 밑에꺼로 변경 --> 
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" maxPostSize="10000000"/>
cs



tomcat 사용할 때 post로 데이터 전송하게 되면

일반적으로는 정상처리되나, 

용량이 너무 크게되면 안됨(default값이 2M인 2097152이다)


비슷하게 maxParameterCount도 있다(get이나 post로 전송시 최대 파라미터 개수)

하지만 maxParameterCount는 default가 10000개이므로 

파라미터 개수로 에러나는 경우는 적을듯


참조 : http://java7.tistory.com/83

'SPRING' 카테고리의 다른 글

스프링 파일 업로드/다운로드  (1) 2018.03.27
스프링에서 한글 인코딩  (0) 2018.03.26
스프링 시큐리티 적용시키기  (1) 2018.03.05

 pom.xml


<!-- fileUpload/download -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
 
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>
cs



web.xml


<filter>
        <filter-name>springMultipartFilter</filter-name>
        <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>springMultipartFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
cs



dispatcher-servlet.xml



<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="52428800"/>    <!-- 50MB -->
        <property name="maxInMemorySize" value="1048576"/>    <!-- 1MB -->
</bean>
cs



FileUtils.java



//다중 파일 업로드
public List<FileVO> multiUploadFile(MultipartHttpServletRequest request) throws IllegalStateException, IOException {
        
    List<FileVO> filelist = new ArrayList<BoardVO>();
    //file이라는 파라미터를 리스트로 받음
    List<MultipartFile> uploadFileList = request.getFiles("file");
        
    for (int i = 0; i < uploadFileList.size(); i++) {
        //파일 원래이름
        String oriFileName = uploadFileList.get(i).getOriginalFilename();
            
        if ((oriFileName != null&& (!oriFileName.equals(""))) {
            String ext = "";
            //확장자 구분
            int index = oriFileName.lastIndexOf(".");
            if (index != -1) {
                ext = oriFileName.substring(index);
            }
            //파일 저장이름
            String saveFileName = "File-" + UUID.randomUUID().toString()+ ext;
            //파일 저장
            uploadFileList.get(i).transferTo(new File("저장경로" + saveFileName));
            filelist.add(i, new BoardVO());
            filelist.get(i).setFileOrgName(oriFileName);
            filelist.get(i).setFileSaveName(saveFileName);
                
            }
        }
        return filelist;
    }
 
//파일 다운로드
public void downloadFile(FileVO fileVO, HttpServletRequest request, HttpServletResponse response) throws Exception {
        
    File file = new File("저장경로", fileVO.getFileSaveName());
 
    BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
 
    //User-Agent : 어떤 운영체제로  어떤 브라우저를 서버( 홈페이지 )에 접근하는지 확인함
    String header = request.getHeader("User-Agent");
    String fileName;
    
    if ((header.contains("MSIE")) || (header.contains("Trident")) || (header.contains("Edge"))) {
        //인터넷 익스플로러 10이하 버전, 11버전, 엣지에서 인코딩 
        fileName = URLEncoder.encode(boardfile.getFileOrgName(), "UTF-8");
    } else {
        //나머지 브라우저에서 인코딩
        fileName = new String(boardfile.getFileOrgName().getBytes("UTF-8"), "iso-8859-1");
    }
    //형식을 모르는 파일첨부용 contentType
    response.setContentType("application/octet-stream");
    //다운로드와 다운로드될 파일이름
    response.setHeader("Content-Disposition""attachment; filename=\""+ fileName + "\"");
    //파일복사
    FileCopyUtils.copy(in, response.getOutputStream());
    in.close();
    response.getOutputStream().flush();
    response.getOutputStream().close();
    }
cs



참조 :    http://androphil.tistory.com/330

     http://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte2:fdl:file_download

'SPRING' 카테고리의 다른 글

스프링 파일 업로드 추가사항  (0) 2018.03.27
스프링에서 한글 인코딩  (0) 2018.03.26
스프링 시큐리티 적용시키기  (1) 2018.03.05

Get전송방식


Servers server.xml

URIEncoding="UTF-8" 추가



<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
->
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>
cs

Post전송방식
web.xml encodingFilter추가

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>*.do</url-pattern>
</filter-mapping>
cs


'SPRING' 카테고리의 다른 글

스프링 파일 업로드 추가사항  (0) 2018.03.27
스프링 파일 업로드/다운로드  (1) 2018.03.27
스프링 시큐리티 적용시키기  (1) 2018.03.05

웹을 통해 데이터를 주고받는 업무를 진행할 경우, 보안상의 문제가 발생하기 쉽다.

Security Service는 웹을 통한 서비스 이용 시 발생할 수 있는 다양한 보안상의 취약점들을 사전에 인지하고 대응함으로써, 서비스의 안정성을 확보한다.

Security Service는 사용자 정보를 DB에서 관리하여 인증을 거쳐야만 접근할 수 있는 Authentication과 사용자 권한 정보를 계층화 시켜서 화면 및 페이지, 또는 메소드에 접근할 수 있는 Authorization이 포함된다.



웹어플리케이션 인증절차


1.리소스 요청

2.요청에 대해 보호되고 있는 자원인지 판단

3.아직 인증이 안되었으므로 HTTP 응답코드(오류) 또는 특정 페이지로 redirect

4.인증 메커니즘에 따라 웹 페이지 로그인 폼 또는 X509 인증서

5.입력 폼의 내용을 HTTP post 또는 인증 세부사항을 포함하는 HTTP 헤더를 서버로 요청

6.신원정보(credential)가 유효한지 판단

7.유효한 경우 다음단계 진행

8.유효하지 않을 경우 신원정보 재요청(되돌아감)

9.보호 자원의 접근 권한이 있을 경우 요청 성공 / 접근 권한이 없을 경우 forbidden 403 HTTP 오류






pom.xml


<!-- security -->
<dependency>
    <groupId>org.springframework.security</groupId>
     <artifactId>spring-security-web</artifactId>
    <version>4.1.2.RELEASE</version>
</dependency>
 
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
     <version>4.1.2.RELEASE</version>
 </dependency>
 
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-taglibs</artifactId>
    <version>4.1.2.RELEASE</version>
</dependency>
 
cs



web.xml



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



context-security.xml





<?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/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.1.xsd">
     
     <!-- url패턴과 스프링 시큐리티를 무시-->
    <security:http pattern="/**/*.js" security="none"/>
    <security:http pattern="/**/*.css" security="none"/>
    <security:http pattern="/images/*" security="none"/>
    
    <!-- 로그인페이지, 기본적인 인증, 로그아웃 기능을 사용, SpEL 사용 -->
    <security:http auto-config="true" use-expressions="true">
         <!-- 세션 관리 -->
        <security:session-management invalid-session-url="/">
            <!-- 동일 ID의 세션 최대수가 한 개, 그 이상일 경우는 기존 세션 무효화 -->
            <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="false" />
        </security:session-management>
        
        <!-- 특정 url 패턴과 그것에 대한 권한 -->
        <security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
         <security:intercept-url pattern="/write.do" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')" method="GET"/>
        <security:intercept-url pattern="/**/update.do" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')"/>
        <security:intercept-url pattern="/**/delete.do" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')"/
        <security:intercept-url pattern="/**" access="permitAll"/>
        
        <!--     
                로그인 폼
                login-page                                :    로그인 폼 페이지
                login-processing-url                     :    로그인 폼 페이지에서 post로 보내는 url
                always-use-default-target="true"일 경우    :    write.do -> login.do -> list.do
                always-use-default-target="false"일 경우 :    write.do -> login.do -> write.do
                default-target-url                        :    인증이 성공하면 redirect로 보내는 url        
                authentication-failure-url                :    로그인 폼 페이지에서 실패할때 보내는 url
                username-parameter                        :    로그인 폼 파라미터 (아이디)
                password-parameter                        :    로그인 폼 파라미터 (비밀번호)
         -->
        <security:form-login 
            login-page="/login.do"
            login-processing-url="/login"
            always-use-default-target="true"
            default-target-url="/list.do"
            authentication-failure-url="/login.do?error=true"
            username-parameter="id"
            password-parameter="password"
        />
        
        <!-- 
            자동로그인  
            key                      :    키 이름
            token-validity-seconds   :    유효시간
            remember-me-parameter    :    로그인 폼 파라미터 (remember-me)
        -->
        <security:remember-me key="remember-key" token-validity-seconds="604800" remember-me-parameter="remember-me-param"/>
        
        <!-- 
            로그아웃
            logout-url            :    로그아웃 url
            logout-success-url    :    로그아웃 정상적일때 보내는 url
            invalidate-session    :    로그아웃 했을때 세션을 무효화 할껀지 설정
            delete-cookies        :    삭제하는 쿠키
         -->
        <security:logout logout-url="/logout" logout-success-url="/list.do" invalidate-session="true" 
            delete-cookies="JSESSIONID,SPRING_SECURITY_REMEMBER_ME_COOKIE"/>
        
    </security:http>
    
    <!-- 인증 관련 설정 -->
    <security:authentication-manager>
        <!-- 인증 제공자, userDetails와 userDetailsService 인터페이스 이용-->
        <security:authentication-provider>
            <!--
                jdbc 베이스로 한  userDetailsService
                data-source-ref                    : 참조할 DB빈 
                users-by-username-query            : 로그인 폼에서 입력된 아이디로 아이디, 비번, 활성화 칼럼을 select해 가져오는 쿼리
                                                     기본 파라미터가 username, password, enabled이므로 db의 칼럼이 다르면 as로 맞춰준다
                authorities-by-username-query     : 로그인 폼에서 입력된 아이디로 아이디, 권한 칼럼을 select해 가져오는 쿼리
                                                    기본 파라미터가 username, authority이므로 db의 칼럼이 다르면 as로 맞춰준다
            -->
            <security:jdbc-user-service
                data-source-ref="dataSource"
                users-by-username-query="select id as username, password, enabled from users where id = ?"
                authorities-by-username-query="select id as username, authority from user_roles where id = ?"
            />
        </security:authentication-provider>
    </security:authentication-manager>
</beans>

cs



Controller.java



@RequestMapping(value="login.do", method=RequestMethod.GET)
public ModelAndView loginForm(ModelAndView mav) {
    UsersVO usersVO = new UsersVO();
        
    mav.addObject("usersVO",usersVO);
    mav.setViewName("login");
    return mav;
}
cs



login.jsp




<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>    
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style type="text/css">
table {
    border: 1px solid black;
    border-collapse: collapse;
}
tr, td {
    border: 1px solid black;
}
</style>
<script type="text/javascript">
function goList() {
    location.href = "${pageContext.request.contextPath}/";
}
</script>
</head
<body>
    <header>스프링 시큐리티 로그인 테스트</header>
    <section>
        <div>
            <form:form commandName="usersVO" action="${ pageContext.request.contextPath}/login"
                <table>
                    <tr>
                        <td>
                            <form:input path="id" placeholder="아이디"/
                        </td
                        <td rowspan="2">
                            <input type="submit" value="로그인">
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <form:password path="password" placeholder="비밀번호"/>
                        </td>
                    </tr>
                    
                </table>
                    <input id="remember_me" name="remember-me-param" type="checkbox"/>아이디 저장
            </form:form>
            <input type="button" value="메인으로" onclick="goList()">
            <br>
            <c:if test="${ error eq 'true' }">
            <!-- 에러메세지와 무슨 에러인지 나타나게해줌 -->
            ${ sessionScope["SPRING_SECURITY_LAST_EXCEPTION"].message }
            <c:remove var="SPRING_SECURITY_LAST_EXCEPTION" scope="session"/>
            </c:if>
        </div>
    </section>
    <footer></footer>
</body>
</html>
cs



access 내장표현식


hasRole([role])

 현재 로그인된 사용자가 지정된 role을 가지고 있으면 true를 반환. 

 제공된 role이 'ROLE_'로 시작하지 않으면 기본적으로 'ROLE_'를 추가.

 hasAnyRole([role1,role2])

 현재 로그인된 사용자가 콤마(,)로 분리하여 주어진 role들 중 하나라도   

 가지고 있으면 true를 반환. 

 제공된 role이 'ROLE_'로 시작하지 않으면 기본적으로 'ROLE_'를 추가. 

 hasAuthority([authority])

 현재 로그인된 사용자가 지정된 권한이 있으면 true를 반환. 

 hasAnyAuthority([authority1,authority2])

 현재 로그인된 사용자가 콤마(,)로 분리하여 주어진 권한들중 하나라도 가지고 있으면 true를 반환. 

 principal

 현재 사용자를 나타내는 principal 객체에 직접 접근가능. 

 authentication SecurityContext로 부터 얻은 Authentication 객체에 직접 접근가능.

 permitAll

 항상 true를 반환. 

 denyAll

 항상 false로 반환. 

 isAnonymous()

 현재 사용자가 익명사용자(로그인 안됨) 사용자이면 true를 반환. 

 isRememberMe()

 현재 로그인된 사용자가 remember-me 사용자이면 true를 반환.

 (로그인 정보 기억 기능에 의한 사용자) 

 isAuthenticated()

 현재 사용자가 로그인된 사용자라면 true를 반환. 

 isFullyAuthenticated()

 로그인 정보 기억(remember-me)이 아니라 아이디/비밀번호를 입력하여 로그인 했다면 true를 반환.

 hasPermission(Object target, Object permission)

 사용자가 주어진 권한으로 제공된 대상에 액세스 할 수 있으면 true를 반환. 

 hasPermission(Object targetId, String targetType, Object permission)

 사용자가 주어진 권한으로 제공된 대상에 액세스 할 수 있으면 true를 반환.



  .jsp


1
2
3
4
5
6
7
8
9
10
<!-- 스프링 시큐리티 태그 -->
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%> 
 
<sec:authorize access="isAuthenticated()"></sec:authorize>
<!-- 현재 인증된 주체에 대해 구성된 액세스 표현식이 참으로 평가되는 경우 태그의 본문을 출력하는 태그 -->
 
<sec:authentication property="principal.username" var="loginID"/>${ loginID }
<!-- 현재의 Authentication 객체에 대한 액세스를 허용. 
var로 할당안하면 바로 출력 var로 할당하면 ${var의 이름}로 해야 출력-->
 
cs

 

 

 참조 :    http://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte2:fdl:server_security:architecture

                 http://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte3:fdl:server_security:authentication

                 http://pentode.tistory.com/144

 

 

 

 

 

 

'SPRING' 카테고리의 다른 글

스프링 파일 업로드 추가사항  (0) 2018.03.27
스프링 파일 업로드/다운로드  (1) 2018.03.27
스프링에서 한글 인코딩  (0) 2018.03.26

+ Recent posts