본문 바로가기

프로그래밍 /SPRING

[SPRING] SPRING SECURITY 로그인 인증


스프링 시큐리티 로그인 인증 1탄 


환경설정 ->Spring STS 4.x/MAC/Apache Tomcat 8.x/mysql5.6.2


스프링 공식 사이트 :  http:// projects..spring.io/spring-security


1. Pom.xml 설정


        <!--스프링시큐리티 web 라이브러리 -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>4.1.0.RELEASE</version>
        </dependency>
        <!--스프링시큐리티 core 라이브러리 -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>4.1.0.RELEASE</version>
        </dependency>
        <!--스프링시큐리티 config 라이브러리 -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>4.1.0.RELEASE</version>
        </dependency>
            <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-taglibs</artifactId>
        <version>4.1.0.RELEASE</version>
        </dependency>



2.web.xml 설정

※(한글인코더 밑에 둘것  위에 있으면 한글 깨질수도 있다.)

       
 <!-- SPRING SECURITY FILTER CHAIN -->
    <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.Spring-security.xml 설정 

  
  <!-- 비밀번호 인코더 -->
  <beans:bean id="bcryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
  
  <!-- 인증매니저 customUserDetailsService를 통해 작업 수행(상기 비밀번호 인코더 참조)-->
  <authentication-manager>
    <authentication-provider user-service-ref ="customUserDetailsService">
      <password-encoder ref="bcryptPasswordEncoder"/>
    </authentication-provider>
  </authentication-manager>
  <!-- 인증실패 핸들러 -->
   <beans:bean id="customAuthenticationFailHandler" class="handler.CustomAuthenticationFailHandler"/>
<!-- 시큐리티 기본 세팅 사용 -->
  <http auto-config='true' use-expressions="true">
 
    <!-- 세션 관리 -->
   <session-management>
      <!-- 동일 ID의 세션 최대수가 한 개, 그 이상일 경우는 기존 세션 무효화 -->
      <concurrency-control max-sessions="1" expired-url="/"/>
    </session-management>
  
    <!-- 인터셉터 --> 따로 인터셉터 Controller사용 x
    <intercept-url pattern="/" access="permitAll" />
    <intercept-url pattern="/user/**" access="permitAll" />
    
    <intercept-url pattern="/explore/**" access="hasAuthority('ROLE_USER')" />
    <intercept-url pattern="/member/**" access="hasAuthority('ROLE_USER')" />
    <intercept-url pattern="/post/**" access="hasAuthority('ROLE_USER')" />
    <intercept-url pattern="/main" access="hasAuthority('ROLE_USER')" />
    
    <!-- 로그인 form 설정 -->    
    <form-login
          login-page="/"
          login-processing-url="/login-processing"
          default-target-url="/"
          username-parameter="email"
          password-parameter="password"
           authentication-failure-handler-ref="customAuthenticationFailHandler"
          />
          
    <!-- 로그아웃 설정 -->
    <!-- 로그아웃 단계 1. 세션 초기화 / 2. SecurityContext초기화 / 3. url redirect -->
    <logout logout-url="/logout" logout-success-url="/?logout=true" invalidate-session="true"/>
                                                                            로그아웃시 세션 정보 삭제
    
        
    <access-denied-handler error-page="/access-denied"/>
  </http>


4.사용자 커스터 마이징 (CustomUserDetails.java)

    
    private String email;
    private String bPass;
    private String nickname;
    private String snsID;
    private boolean enabled;
    private boolean useCookie;
    private String profilephoto;
    
    
    get//setter...

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority("ROLE_USER")); //회원가입한 사람은 누구나 ROLE_USER 권한을 갖는다.
        return authorities;
    }

    @Override
    public String getPassword() {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    public String getUsername() {
        // TODO Auto-generated method stub
        return email;
    }

    @Override
    public boolean isAccountNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }
    @Override
    public boolean isAccountNonLocked() {
        // TODO Auto-generated method stub
        return true;
    }
    @Override
    public boolean isCredentialsNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }
    @Override
    public boolean isEnabled() {
        // TODO Auto-generated method stub
        return true;
    }

}


5.커스터마이징 서비스 

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserService service;

    @Override
    public CustomUserDetails loadUserByUsername(String email)
            throws UsernameNotFoundException {
        
        
        try {
            //이메일 값을 통해 유저정보 가져옴 UserVO형식
            UserVO users = service.detailByEmail(email);
            
            /* * 해당 사용자가 존재하지 않으면
             * 이미 정의된 UsernameNotFoundException을 이용하여
             * 예외를 생성해서 던져주면 스프링이 알아서 예외처리를 하게 된다.
             */
            //사용자 존재하지 않을 경우
            if (users == null) {
                throw new UsernameNotFoundException("해당 사용자를 찾지 못했습니다.");
            }
                
            return new CustomUserDetails(email,
                    users.getPassword(),
                    
                    true, //enabled
                    true, //accountNonExpired
                    true, //credentialsNonExpired
                    true, //accountNonLocked
            
                    this.getGrantedAuthorities(users),
                    users);
            
        } catch (UsersException e) {
            System.out.println(e.getMessage());
        }       
        
        return null;


6.Login JSP (view)

※_csrf.token값을 넘겨 줘야지 post가능


<!-- Login Form -->
<form name="login" action="<c:url value='login-processing'/>"method="post">


<input type="text" class="form-control" id="email" name="email" placeholder="가입한 Email을 입력해주세요" autofocus
<c:if test="${ loginid ne null }">
value="${loginid}"
</c:if>
>
<input type="password" class="form-control" id="password" name="password" placeholder="Password를 입력해주세요" >
<input type="hidden" name="${ _csrf.parameterName }" value="${ _csrf.token }">
<input type="submit" class="form-control btn btn-primary" value="로그인"/>

</form>
<c:if test='${ error eq "login" }'>
<p style="color:#FF0000">이메일 혹은 비밀번호를 잘못 입력하셨습니다.</p>
</c:if>
<c:if test='${ error eq "duplicate" }'>
<p style="color:#FF0000">이미 로그인하고 있는 사용자입니다.</p>
</c:if>
<c:if test='${ error eq "not found" }'>
<p style="color:#FF0000">등록되지 않은 유저입니다.</p>
</c:if>
<c:if test="${ param.logout == 'true' }">
<p style="color:#FF0000">로그아웃 되었습니다.</p>
</c:if>