php -> java + spring 마이그레이션중 Interceptor 방식으로 구현하였으나 마이그레이션 하는 김에… spring security 적용…
로그인 정상적으로 되나… 서버 재시작(세션 초기화) 하였음에도 세션 체크가 되지 않아.. 없었던일로…
나중을 위해 정리…
내 생각으론..
web.xml 에 들어오는 url-pattern 에 의해 security-context.xml 에 정의한
UserDetailsService.java 와 CustomAuthenticationProvider.java
로 각 사용자 정보를 비교하여 인증정보를 저장하여 컨트롤 하는 것으로 보여짐..
UserDetailsService.java 에서는 사용자이름(이름 또는 아이디와 같은 고유값)
을 통해 조회된 정보를 CustomAuthenticationProvider.java의
Authentication authentication 객체에 담아 넘겨줌.
넘겨준 데이터를 통해 패스워드 일치, 권한등을 추가적으로 작업…
- 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 글이 마음에 드셨다면 하트 꾸욱~