Spring security 설정 정리…(스프링시큐리티)

php -> java + spring 마이그레이션중  Interceptor 방식으로 구현하였으나 마이그레이션 하는 김에… spring security 적용…

로그인 정상적으로 되나… 서버 재시작(세션 초기화) 하였음에도 세션 체크가 되지 않아..   없었던일로…

나중을 위해 정리…

내 생각으론..

web.xml 에 들어오는 url-pattern 에 의해 security-context.xml 에 정의한

UserDetailsService.java 와 CustomAuthenticationProvider.java

로 각 사용자 정보를 비교하여 인증정보를 저장하여 컨트롤 하는 것으로 보여짐..

UserDetailsService.java 에서는 사용자이름(이름 또는 아이디와 같은 고유값)

을 통해 조회된 정보를 CustomAuthenticationProvider.java의

Authentication authentication 객체에 담아 넘겨줌.

넘겨준 데이터를 통해 패스워드 일치, 권한등을 추가적으로 작업…

 

  1. web.xml에 추가
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> //filter 처리을 spring security로 위임하는것
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

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

 

2. pom.xml 추가

<dependency>
 <groupId>org.springframework.security</groupId>
 <artifactId>spring-security-core</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>

<dependency>
 <groupId>org.springframework.security</groupId>
 <artifactId>spring-security-taglibs</artifactId>
 <version>4.1.3.RELEASE</version>
</dependency>

<dependency>
 <groupId>org.springframework.security</groupId>
 <artifactId>spring-security-config</artifactId>
 <version>4.1.3.RELEASE</version>
</dependency>

3. security-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"
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">

<!-- expressions을 추가해야 hasRole,permitAll등의 다양한 옵션들을 쓸수 있음 -->
<http auto-config="true" use-expressions="true">
<form-login username-parameter="userId" password-parameter="userPw"
login-page="/index.do" login-processing-url="/login/login.do"
default-target-url="/user/myPage.do" authentication-failure-url="/index.do" />

<!-- 관리자만 들어갈수있음 -->
<intercept-url pattern="/admin/**" access="hasAuthority('ROLE_ADMIN')" /> 
<!-- 인증한사람만 들어갈수있음 -->
<intercept-url pattern="/user/**" access="isAuthenticated()" />
<!-- 누구나 다들어갈수 있음 -->
<intercept-url pattern="/**" access="permitAll" />


<!-- CSRF 보안 관련 처리 -->
<csrf/>

<!-- 사용시 로그인 페이지에서 form 에 추가  -->

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


<beans:bean id="customAuthenticationProvider" class="com.ers.service.CustomAuthenticationProvider" />
<beans:bean id="userDetailService" class="com.ers.service.UserDetailService" />

<authentication-manager alias="authenticationManager">
<authentication-provider ref="customAuthenticationProvider"/>

<authentication-provider user-service-ref="userDetailService">
<!-- <password-encoder ref="passwordEncoder" /> -->
</authentication-provider>
</authentication-manager>
</beans:beans>

 

4. 사용자정보 조회할 UserDetailService.java 구현

package com.ers.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.ers.mapper.LoginMapper;
import com.ers.model.LoginInfoVO;
import com.ers.model.UserDetailVO;

@Service
public class UserDetailService implements UserDetailsService{

@Autowired
private LoginMapper loginMapper;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
LoginInfoVO loginInfoVO = loginMapper.getUserInfo(username);

if(loginInfoVO == null) {
throw new UsernameNotFoundException("사용자 정보를 조회 할 수 없습니다.");
}
ArrayList<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
if("ADM".equals(loginInfoVO.getUserType())) {
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
}else {
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
}

/**
* 스프링 시큐리티 관련 정보
*/
UserDetailVO userDetailVO = new UserDetailVO();
userDetailVO.setUsername(username);
userDetailVO.setPassword(loginInfoVO.getUserPw());
userDetailVO.setEnabled(true);
userDetailVO.setAuthorities(authorities);

/**
* 로그인관련 정보
*/
userDetailVO.setCmpCd(loginInfoVO.getCmpCd());
userDetailVO.setDeptCd(loginInfoVO.getDeptCd());
userDetailVO.setMoSalCd(loginInfoVO.getMoSalCd());
userDetailVO.setUserName(loginInfoVO.getUserName());
userDetailVO.setUserType(loginInfoVO.getUserType());
userDetailVO.setUserId(loginInfoVO.getUserId().toUpperCase());
userDetailVO.setLoginYn("Y");
return userDetailVO;
}
}

 

5. 사용자정보에 대한 인증정보 (사용자정보 있는 경우 후처리)

package com.ers.service;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import com.ers.mapper.LoginMapper;
import com.ers.model.LoginInfoVO;
import com.ers.model.UserDetailVO;

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider{

protected Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired
UserDetailService userDetailService;

@Autowired
private LoginMapper loginMapper;

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
UsernamePasswordAuthenticationToken authToken = (UsernamePasswordAuthenticationToken) authentication;

UserDetailVO userInfo = (UserDetailVO) userDetailService.loadUserByUsername(authToken.getName()); //UserDetailsService에서 유저정보를 불러온다.

if(userInfo == null) {
throw new UsernameNotFoundException(authToken.getName());
}

LoginInfoVO loginInfoVO = loginMapper.getUserInfo(authToken.getName());
if(!matchPassword(userInfo.getPassword(), authToken.getCredentials())) {
throw new BadCredentialsException("not matching username or password");
}

List<GrantedAuthority> authorities = (List<GrantedAuthority>) userInfo.getAuthorities();
return new UsernamePasswordAuthenticationToken(loginInfoVO.getUserId(), loginInfoVO.getUserPw(), authorities);
}

@Override
public boolean supports(Class<?> authentication) {
return true;
}

private boolean matchPassword(String password, Object credentials) {
return password.equals(credentials);
}
}

 

 

0 글이 마음에 드셨다면 하트 꾸욱~