7월 22일
1.로그인과 로그아웃 처리
(1)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"
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">
<security:http>
<security:intercept-url pattern="/sample/all" access="permitAll"/>
<security:intercept-url pattern="/sample/member" access="hasRole('Role_MEMBER')"/>
<security:form-login />
</security:http>
<security:authentication-manager>
</security:authentication-manager>
</beans>
특정한 URI에 접근할때 인터셉터를 이용해서 접근을 제한하는 설정은 <security:intercept-url>을 이용함.
<security:intercept-url>은 pattern이라는 속성과 access속성을 지정한다.
pattern은 uri패턴을 의미하고, access는 권한을 체크.
실행해보면 member는 자동으로 로그인페이지로 이동하는데,스프링시큐리티가 기본으로 제공해주는 페이지임.
*혼동하지 않도록 주의!!!
스프링시큐리티에서는 username 은 userid 와 같다!!!
스프링시큐리티에서는 User는 인증정보와 권한을 가진 객체이므로 일반적인 경우에 사용하는 사용자 정보와는 다른 의미. VO와 같은 역할을 함.
(2)UserDetailsService 처리
인증과 권한에 대한 실제 처리는 UserDetailsService 라는 것을 이용해서 처리
security-context.xml 수정한다.
*단,스프링시큐리티 5버젼부터 반드시 PasswordEncoder를 지정해야함.
PasswordEncoder처리없이 사용하고싶다면 패스워드 앞에'{noop}' 문자열을 추가해야함.
<?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"
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">
<security:http>
<security:intercept-url pattern="/sample/all" access="permitAll"/>
<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')"/>
<security:form-login />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<!-- 패스워드의 인코딩 처리 없이 사용하고 싶다면 패스워드 앞에 '{noop}member' -->
<security:user name="member" password="{noop}member" authorities="ROLE_MEMBER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
(3)JSESSIONID
로그인정보를 담고있는 쿠키가 있는데, WAS마다 다른 이름을 사용,
톰캣에서는 'JSESSIONID' 라고 부르며, 세션을 유지하는데 사용되는 세션 쿠키이다.
JSESSIONID 이부분을 삭제하면 로그인정보가 없어지면서 로그아웃이 됨
2.여러 권한을 가지는 사용자 설정
ROLE_ADMIN 과 ROLE_MEMBER 2개의 권한을 가지도록 설정
(1)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"
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">
<security:http>
<security:intercept-url pattern="/sample/all" access="permitAll"/>
<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')"/>
<security:intercept-url pattern="/sample/admin" access="hasRole('ROLE_ADMIN')"/>
<security:form-login />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<!-- 패스워드의 인코딩 처리 없이 사용하고 싶다면 패스워드 앞에 '{noop}member' -->
<security:user name="member" password="{noop}member" authorities="ROLE_MEMBER"/>
<security:user name="admin" password="{noop}admin" authorities="ROLE_ADMIN"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
member로 로그인 하면 member 페이지만 확인가능한데,
admin으로 로그인 하면 admin,member 둘다 페이지확인 가능하다.
3.접근제한 메세지 처리
특정한 사용자가 로그인했지만, uri를 접근할 수 있는 권한이 없는데 접근할경우 접근제한에러 메세지를 처리해야함.
스프링 시큐리티에서는 접근제한에 대해서 AccessDeniedHandler를 직접구현하거나 특정한 uri를 지정할 수 있다.
(1)security-context.xml 수정
accessError 라는 uri로 접근제한 시 보이는 화면을 처리함
<?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"
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">
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/sample/all" access="permitAll"/>
<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')"/>
<security:intercept-url pattern="/sample/admin" access="hasRole('ROLE_ADMIN')"/>
<security:form-login />
<!-- /accessError 라는 uri로 접근제한 시 보이는 화면을 처리-->
<security:access-denied-handler error-page="/accessError"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="member" password="{noop}member" authorities="ROLE_MEMBER"/>
<security:user name="admin" password="{noop}admin" authorities="ROLE_ADMIN"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
(2)CommonController 작성하기
Authentication 파라미터를 받아 필요한 경우에 사용자의 정보를 확인할 수 있도록 함
사용자가 알아볼수 있는 에러메세지를 model에 담아서 전달
package com.keduit.controller;
@Controller
@Log4j
public class CommonController {
@GetMapping("/accessError")
public void accessDenied(Authentication auth,Model model) {
/* Authentication 파라미터를 받아 필요한 경우에 사용자의 정보를 확인할 수 있도록 함 */
log.info("access Denied : "+auth);
/* 사용자가 알아볼수 있는 에러메세지를 model에 담아서 전달 */
model.addAttribute("msg","Access Denied");
}
}
(3)accessError.jsp 작성
jsp에서 HttpServlet Request안에 'SPRING_SECURITY_403_EXCEPTION.getMessage'이라는 이름으로 Access DeniedException 객체가 전달 됨
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec" %>
<%@ page import="java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Access Denied Page</h1>
<h2><c:out value="${SPRING_SECURITY_403_EXCEPTION.getMessage()}"/></h2>
<h2><c:out value="${msg}"/></h2>
</body>
</html>