1. 이클립스 삭제 후 재설치 시 발생하는 에러

 - ERROR: org.eclipse.equinox.p2.engine code=4 An error occurred during the org.eclipse.equinox.internal.p2.engine.phases.CheckTrust phase.

 

내 문서의 .eclipse, .m2, .p2 폴더 삭제

 

2. 프로젝트 선택 시 발생하는 에러

- please choose another workspace as

 

해당 프로젝트의 metadata폴더 삭제

CSS를 사용하기 위한 Selector, Combinators(선택자, 결합자(space, >, +, ~))이다.

 

1. Class 선택자.

1-1. 기본 중 하나인 Class 선택자이다.

스타일 태그서 .아이디{ } 로 사용한다.

코드 :

<div class="class-selector">
 	CSS Class Selector - { font-size : 30px; }
</div>

<style>
  .class-selector{
              font-size : 30px;
  }
</style>

 

결과 : 

 

1-2. 특정 태그에만 사용하게 하는 Class 선택자이다. 

특정 태그.클래스명을 적으면 사용가능하다.

아래 코드와 같이 같은 클래스를 사용해도 style에서 태그를 지정해주면 다르게 적용된다.

<div class="class-selector-2">
	CSS Class Selector - { font-size : 30px; color : red; } Not Apply
</div>
<p class="class-selector-2">
	CSS Class Selector - { font-size : 30px; color : red; }
</p>

<style>
p.class-selector-2{
            font-size: 30px;
            color : red;
}
</style>

 

결과 : 

 

2. ID 선택자

기본 중 하나인 ID 선택자이다. 앞에 #을 붙여 사용가능하다.

코드 :

<div id="id-selector">
	CSS ID Selector - { background-color : black; color: white;}
</div>

<style>
        #id-selector{
            background-color : black;
            color : white;
        }
</style>

결과 : 

 

3. Group 선택자 ( , )

element에 같은 Style을 적용하기 위한 선택자이다. 사용할 element들에 콤마로 나열하여 사용가능하다.

코드 :

<div class="comma-1">
	CSS Comma 1 - { color : red; }
</div>

<div class="comma-2">
	CSS Comma 2 - { color : red; }
</div>
        
<style>
        .comma-1,
        .comma-2{
            color : red;
        }
</style>

결과 :

 

4. 결합자(space, >, + ~)

4-1. 자손 선택자 Descendant ( space )

CSS에서 Space로 표현하는 것으로 특정 element 내부에 있는 특정한 모든 element에 적용된다.

아래와 같이 특정 element(descedant-1) 내부에 있는 특정한 모든 element(descedant-2)에 적용된다.

또한 descedant-1 내부의 nothing이라는 class 내부에 있어도 descedant-2 가 적용된다.

코드 : 

        <div class="descendant-1">
            <div class="descendant-2">
                    CSS Descendant - { color : yellow; }
            </div>
            <div class="nothing">
                <div class="descendant-2">
                        CSS Descendant -{ color : yellow; }
                 </div>   
            </div>

            <div class="descendant-2">
                    CSS Descendant - { color : yellow; }
            </div>
        </div>
        
<style>
        .descendant-1 .descendant-2{
            background-color : yellow;
        }
</style>

결과 : 

 

4-2. 자식 선택자 Child ( > )

CSS에서 > (부등호)로 표현하는 것으로 자손 선택자와 마찬가지로 특정 element 내부에 있는 특정한 모든 element에 적용된다.

아래와 같이 특정 element(descedant-1) 내부에 있는 특정한 모든 element(descedant-2)에 적용된다.

하지만 자손선택자와 다른점은 descedant-1 내부의 nothing이라는 class 내부에 있으면 descedant-2 가 적용되지 않고 무조건 descedant-1 의 바로 내부에만 있어야 적용된다.

코드 :

<div class="child-1">
    <div class="child-2">
    	CSS Child - { color : green; }
	</div>
    <div calss="nothing">
        <div class="child-2">
            CSS Child - { color : green; } Not Apply
        </div>   
    </div>

	<div class="child-2">
  		CSS Child - { color : green; }
  	</div>
</div>

<style>
        .child-1 > .child-2{
            background : green;
        }
</style>

결과 : 

 

4-3. 인접 형제 선택자 Adjacent Sibling ( + )

CSS에서 +로 표현하는 것으로 특정한 element 바로 다음에 오는 특정한 element 하나만적용되는 것이다.

아래의 코드처럼 adjacent-1 내부에 adjacent-2 가 있어도 적용되지 않고 항상 특정 element가 닫힌 뒤 바로 다음에 와야 적용이된다. 

또한, 하나만 적용되기 때문에 아래 코드의 마지막 줄은 적용되지 않았다.

코드 :

        <div class="adjacent-1">
            CSS Adjacent - { color : grey; } Not Apply
            <div class="adjacent-2">
                CSS Adjacent - { color : grey; } Not Apply
            </div>
        </div>
        <div class="adjacent-2">
            CSS Adjacent - { color : grey; }
        </div>
        <div class="adjacent-2">
            CSS Adjacent - { color : grey; } Not Apply
        </div>
        
<style>
        .adjacent-1 + .adjacent-2{
            background-color : grey;
        }
</style>

결과 : 

 

4-4. 일반 형제 선택자 General Sibling ( ~ )

CSS에서 ~로 표현하는 것으로 특정한 element 바로 다음에 오는 모든 특정한 element들이 적용된다.

아래의 코드처럼 general-1 내부에 general-2 가 있어도 적용되지 않고 항상 특정 element가 닫힌 뒤 바로 다음에 와야 적용이된다. 

인접 형제 선택자와 달리 하나만 적용되는 것이 아니라 모두 적용되어 아래코드의 마지막 줄도 적용이 되어있다.

코드 :

        <div class="general-1">
            CSS General - { color : blue; } Not Apply
            <div class="general-2">
                    CSS General - { color : blue; } Not Apply
            </div>
        </div>

        <div class="general-2">
            CSS General - { color : blue; }
        </div>

        <div class="general-2">
            CSS General - { color : blue; }
        </div>

        <div class="nothing">
            <div class="general-2">
                CSS General - { color : blue; } Not Apply
            </div>
        </div>

        <div class="general-2">
                CSS General - { color : blue; }
        </div>
        
<style>
        .general-1 ~ .general-2{
            background-color : blue;
        }
</style>

결과 : 

 

사용된 모든 예제 소스 및 결과화면

<html>  
    <head>
        <title>
            CSS TEST
        </title>
    </head>
    <body>
        <div class="class-selector">
            CSS Class Selector - { font-size : 30px; }
        </div>
        <hr/>

        <div class="class-selector-2">
                CSS Class Selector - { font-size : 30px; color : red; } Not Apply
        </div>
        <p class="class-selector-2">
                    CSS Class Selector - { font-size : 30px; color : red; }
        </p>
        <hr/>

        <div id="id-selector">
                CSS ID Selector - { background-color : black; color: white;}
        </div>
        <hr/>

        <div class="comma-1">
            CSS Comma 1 - { color : red; }
        </div>

        <div class="comma-2">
            CSS Comma 2 - { color : red; }
        </div>
        <hr/>

        <div class="descendant-1">
            <div class="descendant-2">
                    CSS Descendant - { color : yellow; }
            </div>
            <div calss="nothing">
                <div class="descendant-2">
                        CSS Descendant -{ color : yellow; }
                 </div>   
            </div>

            <div class="descendant-2">
                    CSS Descendant - { color : yellow; }
            </div>
        </div>
        <hr/>

        <div class="child-1">
            <div class="child-2">
                    CSS Child - { color : green; }
            </div>
            <div calss="nothing">
                <div class="child-2">
                        CSS Child - { color : green; } Not Apply
                    </div>   
            </div>

            <div class="child-2">
                    CSS Child - { color : green; }
            </div>
        </div>
        <hr/>

        <div class="adjacent-1">
            CSS Adjacent - { color : grey; } Not Apply
            <div class="adjacent-2">
                CSS Adjacent - { color : grey; } Not Apply
            </div>
        </div>
        <div class="adjacent-2">
            CSS Adjacent - { color : grey; }
        </div>
        <div class="adjacent-2">
            CSS Adjacent - { color : grey; } Not Apply
        </div>
        <hr/>

        <div class="general-1">
            CSS General - { color : blue; } Not Apply
            <div class="general-2">
                    CSS General - { color : blue; } Not Apply
            </div>
        </div>

        <div class="general-2">
            CSS General - { color : blue; }
        </div>

        <div class="general-2">
            CSS General - { color : blue; }
        </div>

        <div class="nothing">
            <div class="general-2">
                CSS General - { color : blue; } Not Apply
            </div>
        </div>

        <div class="general-2">
                CSS General - { color : blue; }
        </div>
    </body>

    <style>
        .class-selector{
            font-size : 30px;
        }
        p.class-selector-2{
            font-size: 30px;
            color : red;
        }
        #id-selector{
            background-color : black;
            color : white;
        }
        
        .comma-1,
        .comma-2{
            color : red;
        }

        .descendant-1 .descendant-2{
            background-color : yellow;
        }

        .child-1 > .child-2{
            background : green;
        }

        .adjacent-1 + .adjacent-2{
            background-color : grey;
        }

        .general-1 ~ .general-2{
            background-color : blue;
        }
    </style>
</html>

 

1. 먼저 필요한 Maven을 설치합니다.

아래의 메이븐저장소에 들어가서 spring-security-core, spring-security-web, spring-security-config, pring-security-taglibs 검색하여 pom.xml에 추가합니다.

https://mvnrepository.com/

 

Maven Repository: Search/Browse/Explore

Reactivewizard Binding Last Release on Oct 31, 2019

mvnrepository.com

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

 

2. web.xml 에 들어가 아래와 같이 추가합니다.

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

<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. 로그인 창을 하나 만듭니다.

파일이름은 login.jsp로 만들었습니다.

<!-- login.jsp -->
<form action="loginProcess" method="post">
<input type="text" name="userId">
<input type="password" name="userPw">
<input type="submit" value="ok">
</form>

 

4. /WEB-INF/spring 폴더 밑에 security-context.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"

	xmlns:context="http://www.springframework.org/schema/context"

	xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd

        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


	<security:http auto-config='true' use-expressions="true">
		<security:csrf disabled="true" />
        
		<security:intercept-url pattern="/login"
			access="permitAll" />

		<security:intercept-url pattern="/**"
			access="isAuthenticated()" />

		<security:form-login login-page="/login"
			username-parameter="userId" password-parameter="userPw"
			login-processing-url="/loginProcess" default-target-url="/test"
			authentication-failure-url="/login?failure"
			always-use-default-target='true' />
            
		<security:logout invalidate-session="true"
			logout-url="/logout" logout-success-url="/login?logout" />
	</security:http>


</beans>

대충 설명하자면 /login 주소는 권한이없어도 접속을 허용하겠다는 뜻이고

그 외 주소는 로그인 인증이 되어야 접속할 수 있도록 하겠다는 뜻입니다.

그 외를 알고싶으시면 use-expressions(SpEL) 을 찾아보시면 됩니다.

그리고 3번에서 만든 로그인페이지를 등록하고 3번에서 만든 각각 id, passwordname들을 지정합니다.

또한 login-proccessing-url에 3번에서 만든 action 의 주소를 입력합니다. 여기서는 loginProcess로 되어있지만 아무거나 해도됩니다.

login-proccessing-url은 로그인 처리를 해주는 url인데 이름만 정해주면 security 측에서 알아서 만들어주는 url으로써  이름만 정하면 따로 저희가 할 일은 없이 spring security가 로그인처리를 진행 해줍니다.

default-target-url은 로그인성공시 접속할 주소를 입력합니다.

auauthentication-failure-url 은 로그인 실패시 처리할 주소를 입력하시면 됩니다.
always-use-default-target='true' 로그인 성공후 default-target-url에 설정한 곳으로 갈지 선택하는 것입니다.

invalidate-session="true" logout-url="/logout" logout-success-url="/login?logout" 로그아웃 입니다. 로그아웃 경로를 저장하고 로그아웃 성공시 돌아갈 경로를 저장해주면 로그아웃이 됩니다. 이 로그아웃url 또한 security 측에서 알아서 만들어주는 url으로써 여기서 이름만 정하면 따로 저희가 만들일 없이 spring security가 알아서 로그아웃을 진행해 줍니다.

 

5. 그리고 위의 security-context.xml 안에 로그아웃 밑에 바로 아래와 같이 추가합니다.

	<security:authentication-manager>

		<security:authentication-provider

			user-service-ref="loginService">

			<security:password-encoder

				ref="bcryptPasswordEncoder" />

		</security:authentication-provider>

	</security:authentication-manager>


	<bean id="loginService" class="net.test.test.service.testService" />

	<bean id="bcryptPasswordEncoder"

		class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

로그인 진행시 아이디를 가지고 비밀번호를 비교할 서비스클래스를 정하는 것입니다.

또한 데이터베이스에 비빌번호가 bcrypt로 저장되어 있을 경우 비밀번호 비교시 bcrypt로 비밀번호를 비교하기 위해 설정해줍니다.

 

6. 위에서 아이디를 가지고 비밀번호를 비교할 서비스를 생성합니다.

여기서 DB베이스에서 회원정보를 불러와 암호화되어있는 비밀번호를 비교하게됩니다.

public class testService implements UserDetailsService {

	@Autowired
	TestDAO testDAO;

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		// TODO Auto-generated method stub
		loginVO userVO = testDAO.selectLogin(username);

		if (userVO == null) {
			throw new UsernameNotFoundException("No user found with id");

		}

		Collection<SimpleGrantedAuthority> roles = new ArrayList<SimpleGrantedAuthority>();

		roles.add(new SimpleGrantedAuthority("ROLE_USER"));

		UserDetails user = new User(userVO.getId(), userVO.getPassword(), roles);
		return user;

	}

}

UserDetailsService라는 것을 implements합니다.

그리고 username을 통해 데이터베이스에서 회원정보를 가져오고

roles에 유저를 선택한 다음 UserDetails를 생성하여 return 만 해주면 Spring Security가 알아서 비밀번호를 데이터베이스에 있는 것과 form에서 넘어온 비밀번호를 비교하여 맞으면 로그인성공해주고 아니면 로그인실패를 해줍니다.(그냥 조회만 했을 뿐인데 알아서 다 해줌)

 

이렇게 bean설정과 UserDetails만 설정하면 로그인form에서 아이디하고 비밀번호를 전달한 뒤 아이디만 조회했을 뿐인데 spring security가 로그인처리까지 다 진행해줍니다.

다음 controller에서 Authentication을 통해 로그인한 정보(아이디)를 가져와 사용할 수 있습니다.

'Develop > Spring' 카테고리의 다른 글

Spring Tomcat JNDI 설정  (0) 2020.11.17
Spring Security Custom Filter  (0) 2020.11.09
Spring security 로그인(DB에 있는 아이디 조회)  (0) 2019.11.02
Spring Mybatis + MariaDB(HikariCP) 설정  (0) 2019.10.24
Spring 3 에서 4로 migration  (0) 2019.10.22

+ Recent posts