반응형
###############################################################
## 작업 #1 프로젝트 준비
## WEB-INF/lib
commons-logging.jar
org.springframework.aop-3.0.1.RELEASE.jar
org.springframework.asm-3.0.1.RELEASE.jar
org.springframework.beans-3.0.1.RELEASE.jar
org.springframework.context-3.0.1.RELEASE.jar
org.springframework.core-3.0.1.RELEASE.jar
org.springframework.expression-3.0.1.RELEASE.jar
org.springframework.transaction-3.0.1.RELEASE.jar
org.springframework.web-3.0.1.RELEASE.jar
spring-security-config-3.0.2.RELEASE.jar
spring-security-core-3.0.2.RELEASE.jar
spring-security-web-3.0.2.RELEASE.jar
###############################################################
## 작업 #2 초간단 HTTP 보안
## web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext*.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>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
## applicationContext-security.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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<http auto-config='true'>
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="jimi" password="jimis" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="bobs" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
## /index.jsp
<h1>메인 페이지</h1>
<br/>
<a href="/admin">관리자 페이지</a>
## /admin/index.jsp
<h1>Admin Main Page</h1>
Administrator only!!!
<br/>
<a href="/">메인 페이지</a>
###############################################################
## 응용 #1 직접 만든 로그인 폼
## applicationContext-security.xml
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<form-login login-page="/login.jsp"/>
## login.jsp
<h1>로그인 페이지</h1>
<form name='f' action='/j_spring_security_check' method='POST'>
<table border="1">
<tr><td>아이디 </td><td><input type='text' name='j_username' value=''></td></tr>
<tr><td>비밀번호 </td><td><input type='password' name='j_password'/></td></tr>
<tr><td colspan='2'><input name="submit" type="submit" value="로그인"/></td></tr>
</table>
</form>
###############################################################
## 응용 #2 로그아웃
## /index.jsp
<br/>
<a href="/j_spring_security_logout">로그아웃</a>
###############################################################
## 응용 #3 사용자 로그인 확인
## index.jsp
<%@page import="org.springframework.security.core.*"%>
<%@page import="org.springframework.security.core.context.*"%>
<%@page import="org.springframework.security.core.userdetails.*"%>
<%
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = null;
boolean isAnonymous = true;
if (principal instanceof UserDetails) {
username = ((UserDetails) principal).getUsername();
isAnonymous = false;
} else {
username = principal.toString();
isAnonymous = true;
}
%>
...
<%
if(isAnonymous) {
%>
<a href="/login.jsp">로그인</a>
<%
} else {
%>
<%=username %>님 반갑습니다!
<br/>
<a href="/j_spring_security_logout">로그아웃</a>
<%
}
%>
###############################################################
## 응용 #4 친절한 안내
## applicationContext-security.xml
<http auto-config='true' access-denied-page="/noAuthorized.jsp">
## noAuthorized.jsp
<h1>접근 권한 없음!!</h1>
<br/>
<a href="/">메인 페이지</a>
###############################################################
## 응용 #5 로그인 실패 메시지
## applicationContext-security.xml
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error"/>
## login.jsp
<%@page import="org.springframework.security.core.*"%>
<%@page import="org.springframework.security.web.authentication.*"%>
<%
boolean loginError = request.getParameter("login_error") != null;
String errorMsg = "none";
if (loginError) {
AuthenticationException ex = (AuthenticationException) session.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY);
errorMsg = ex != null ? ex.getMessage() : "none";
}
%>
...
<%
if(loginError) {
if("Bad credentials".equals(errorMsg)) {
%>
<font color="red">아이디나 비밀번호 입력이 틀렸습니다.</font>
<%
} else {
%>
<font color="red">로그인 에러 : <%=errorMsg %></font>
<%
}
}
%>
###############################################################
## 응용 #6 로그인 성공 페이지
## applicationContext-security.xml
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error"
default-target-url="/" always-use-default-target="true"/>
###############################################################
## 응용 #7 특정 URL 통과시키기
## applicationContext-security.xml
<intercept-url pattern="/login.jsp" filters="none"/>
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error"
default-target-url="/" always-use-default-target="true"/>
###############################################################
## 응용 #8-1 동시에 1명만 접속(기존 세션 만료)
## applicationContext-security.xml
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error"
default-target-url="/" always-use-default-target="true"/>
<session-management>
<concurrency-control max-sessions="1"/>
</session-management>
###############################################################
## 응용 #8-2 동시에 1명만 접속(로그인 에러)
## applicationContext-security.xml
<session-management>
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>
</session-management>
###############################################################
## 응용 #9 사용자 정보 DB에서 가져오기
## postgresql-8.4-701.jdbc4.jar
## org.springframework.jdbc-3.0.1.RELEASE-A.jar
## db
create table users(
username varchar(50) not null primary key,
password varchar(50) not null,
enabled boolean not null);
create table authorities (
username varchar(50) not null,
authority varchar(50) not null,
constraint fk_authorities_users foreign key(username) references users(username));
create unique index ix_auth_username on authorities (username,authority);
INSERT INTO users(username, "password", enabled) VALUES ('bob', 'bobs', true);
INSERT INTO users(username, "password", enabled) VALUES ('jimi', 'jimis', true);
INSERT INTO authorities(username, authority) VALUES ('bob', 'ROLE_USER');
INSERT INTO authorities(username, authority) VALUES ('jimi', 'ROLE_USER');
INSERT INTO authorities(username, authority) VALUES ('jimi', 'ROLE_ADMIN');
## applicationContext-security.xml
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="securityDataSource" />
</authentication-provider>
</authentication-manager>
..
<beans:bean id="securityDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="org.postgresql.Driver" />
<beans:property name="url" value="jdbc:postgresql:security" />
<beans:property name="username" value="security" />
<beans:property name="password" value="security" />
</beans:bean>
/** 심화 **/
###############################################################
## 심화 #1 메서드 권한제어
## com.springsource.org.aopalliance-1.0.0.jar
## com.springsource.org.aspectj.tools-1.6.6.RELEASE.jar
## com.springsource.net.sf.cglib-2.1.3.jar
## org.springframework.web.servlet-3.0.1.RELEASE-A.jar
## web.xml
<servlet>
<servlet-name>security</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>security</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
## security-servlet.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="my.controller" />
<context:annotation-config />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
## my.controller.MyController.java
@Controller
public class MyController {
@RequestMapping("/mvcHello")
public void mvcHello() {
}
}
## WEB-INF/view/mvcHello.jsp
<h1>MVC Hello</h1>
## applicationContext-security.xml
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error"
default-target-url="/" always-use-default-target="true"/>
----
## applicationContext-security.xml
<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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
...
<context:component-scan base-package="my.service" />
<global-method-security secured-annotations="enabled"/>
## my.service.MyService.java
@Service
public class MyService {
@Secured("ROLE_ADMIN")
public String getSecurity() {
return "success";
}
}
## my.controller.MyController.java
@Autowired MyService myService;
@RequestMapping("/hasSomeSecurity")
public void hasSomeSecurity(Model model) {
String result = myService.getSecurity();
model.addAttribute("result", result);
}
## index.jsp
<a href="/hasSomeSecurity.do">보안 페이지</a>
<br/>
## WEB-INF/view/hasSomeSecurity.jsp
<h1>무언가 보안요소를 가지고 있는 페이지</h1>
보안결과 : ${result }
###############################################################
## 심화 #2 MyUserDeatilsService
## applicationContext-security.xml
<authentication-manager>
<authentication-provider user-service-ref="myUserDetailsService"/>
</authentication-manager>
<beans:bean id="myUserDetailsService"
class="my.service.MyUserDetailsService">
<beans:property name="myDao">
<beans:bean class="my.dao.MyDao">
<beans:property name="dataSource" ref="securityDataSource"/>
</beans:bean>
</beans:property>
</beans:bean>
## my.domain.MyUserDetails
public class MyUserDetails implements UserDetails {
private String username;
private String password;
private boolean isEnabled = true;
private boolean isAccountNonExpired = true;
private boolean isAccountNonLocked = true;
private boolean isCredentialsNonExpired = true;
private Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
public MyUserDetails(String username, String password) {
this.username = username;
this.password = password;
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return isAccountNonExpired;
}
@Override
public boolean isAccountNonLocked() {
return isAccountNonLocked;
}
@Override
public boolean isCredentialsNonExpired() {
return isCredentialsNonExpired;
}
@Override
public boolean isEnabled() {
return isEnabled;
}
}
## my.service.MyUserDetailsService
public class MyUserDetailsService implements UserDetailsService {
private MyDao myDao;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
UserDetails userDetails = myDao.getUserDetails(username);
Collection<GrantedAuthority> authorities = myDao.getAuthorities(username);
userDetails.getAuthorities().addAll(authorities);
return userDetails;
}
public void setMyDao(MyDao myDao) {
this.myDao = myDao;
}
}
## my.dao.MyDao.java
public class MyDao extends JdbcDaoSupport {
public static final String DEF_USERS_BY_USERNAME_QUERY =
"select username,password " +
"from users " +
"where username = ?";
public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY =
"select username,authority " +
"from authorities " +
"where username = ?";
public UserDetails getUserDetails(String username) {
List<UserDetails> userDetailsList = getJdbcTemplate().query(DEF_USERS_BY_USERNAME_QUERY, new String[] {username}, new RowMapper<UserDetails>() {
public UserDetails mapRow(ResultSet rs, int rowNum) throws SQLException {
String username = rs.getString(1);
String password = rs.getString(2);
return new MyUserDetails(username, password);
}
});
if(userDetailsList.size() == 1)
return userDetailsList.get(0);
else
return null;
}
public Collection<GrantedAuthority> getAuthorities(String username) {
return getJdbcTemplate().query(DEF_AUTHORITIES_BY_USERNAME_QUERY, new String[] {username}, new RowMapper<GrantedAuthority>() {
public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException {
String roleName = rs.getString(2);
return new GrantedAuthorityImpl(roleName);
}
});
}
}
###############################################################
## 심화 #3 XML-Based Configuration
## applicationContext-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/login.jsp" filters="none"/>
<sec:filter-chain pattern="/sessionExpired.jsp" filters="none"/>
<sec:filter-chain pattern="/**" filters="
securityContextPersistenceFilter,
logoutFilter,
formLoginFilter,
exceptionTranslationFilter,
filterSecurityInterceptor" />
</sec:filter-chain-map>
</bean>
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<property name="securityContextRepository">
<bean class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/>
</property>
</bean>
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg><bean class="org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler"/></constructor-arg>
<constructor-arg><bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/></constructor-arg>
<property name="filterProcessesUrl" value="/j_spring_security_logout"></property>
</bean>
<bean id="formLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="filterProcessesUrl" value="/j_spring_security_check"/>
<property name="authenticationSuccessHandler">
<bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/"></property>
<property name="alwaysUseDefaultTargetUrl" value="true"></property>
</bean>
</property>
<property name="authenticationFailureHandler">
<bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/login.jsp?login_error"></property>
</bean>
</property>
<property name="sessionAuthenticationStrategy">
<bean class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<constructor-arg>
<bean class="org.springframework.security.core.session.SessionRegistryImpl"></bean>
</constructor-arg>
<property name="maximumSessions" value="1"></property>
</bean>
</property>
</bean>
<bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<bean class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/login.jsp"/>
</bean>
</property>
<property name="accessDeniedHandler">
<bean class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/noAuthorized.jsp"/>
</bean>
</property>
</bean>
<bean id="filterSecurityInterceptor"
class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="securityMetadataSource">
<sec:filter-security-metadata-source>
<sec:intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<sec:intercept-url pattern="/**" access="ROLE_USER" />
</sec:filter-security-metadata-source>
</property>
</bean>
<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<bean class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="myUserDetailsService" />
</bean>
</property>
</bean>
<bean id="myUserDetailsService"
class="my.service.MyUserDetailsService">
<property name="myDao">
<bean class="my.dao.MyDao">
<property name="dataSource" ref="securityDataSource"/>
</bean>
</property>
</bean>
<bean id="securityDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql:security" />
<property name="username" value="security" />
<property name="password" value="security" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.ConsensusBased">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter"></bean>
</list>
</property>
</bean>
<context:component-scan base-package="my.service" />
<sec:global-method-security secured-annotations="enabled"></sec:global-method-security>
</beans>
반응형
'개발 > JAVA' 카테고리의 다른 글
java RedirectAttributes 사용시 주의점 (0) | 2018.11.26 |
---|---|
java pdf 생성 라이브러리 (0) | 2018.11.26 |
서버에서 OPEN API 연결 예제 (0) | 2018.05.08 |
[JAVA/자바] Jad Decompiler 설치 및 사용 (0) | 2018.02.09 |
GPKI 인증서 로그인 관련 설정 (0) | 2018.01.14 |