spring security
: 정보보안이아님 . (정보보안은 암호화나 하드웨어, 보안솔루션에 대해서 얘기하는거임 ->RSA 암호화모듈)
그럼 스프링시큐리티는 뭘 얘기하는거? ->
인증 Authentication
(누구냐?-지금 애플리케이션확인하는 사용자확인->username, password, enable 이 필요),
인허가 Authority
(권한여부 확인-기능에 따른 권한을 분류하고, 권한을 확인(ROLE_USER..),, 권한에 따른 기능의 차등
-> 승계권한(어드민권한있으면 자연스레 매니저권한도 가지게되는것)이 아니다!
-> 권한부여방식 (어던 사람이 매니저와 어드민의 권한을 가져야한다면 둘다 준다))
원래부터 스프링에 담겨져잇던 애가 아니라, 스프링3버전일떄 시큐리티는 2/3버전으로, 매칭이 잘 안됨
스프링이 4버전되면서 웹접인 이슈(인증부분이 강화됨. 개인정보보호에 관심많아지면서 채택된 표준이 Auth2.0) 이떄 시큐리티가 Auth2.0을 담아서 4버전을 만듦
우리는 4버전을 배울거임

스프링시큐리티는필터로 구현이되어잇꼬 (필터니까 여기서 안맞으면 아예 디스패처서블리승로못감)
~토큰에 사용자가 작성한 아이디/패스워드/상태정보가 들어있음 이 안에 유저디테일이 잇음
프로바이더는 인증방식을 구분하고 실제인증절차를 진행함. 유저디테일 서비스가 서비스에 컨택해서 담긴 사용자정보를 프로바이더가 비교를 하는거임
비교대상을 결정하는건 프로바이더
그래서 성공인지실패인지의 정보를 매니저에게줌
매니저밑에 각종핸들러가 달려잇음
그 핸들러들이 결과에대한 피드백을 사용자에게줌
web.xml 에서 필터와 디스패처서블렛과 서비스가 서블릿이닛()을 통해서동시에 로딩되기떄문에
필터에서 서비스를 떙겨서 데이터를 끌어써야하는데 안끌어짐 (동시에 로딩되기떄문에) 그래서
필터에서 추가로 빈 컨테이너를 따로로딩해서 떙겨야함
genericxmlapplicationcontext이용할수잇다
또한
매니저밑의 석세스핸들러쪽에서 추가로 톰캣세션에 넣어줘야 우리가 실제로 쓰는 톰캣의 세션에 그 결과가 들어감
시큐리티 안쓰면
매번 기능에 따라 권한을 ㅎ확인해야하므로 컨트롤러에 중복코드가 계속생김
시큐리티는 이게 편해질수잇음
시큐리티는 인사권자는 연봉정보가 다 보이고 .. 이런걸 쓰기위해 태그라이브러리도 지원해줌
암튼 모든 기능의 시작은 필터다
시큐리티는 총 3가지 디펜던디
기본적인 필터갖고잇는 웹, 그안의 설정할수잇는 시큐리티컨피그, 화면단에서 태그라이브러리 지원하는 태그라이브러리
<org.springframework-security>3.2.3.RELEASE</org.springframework-security>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${org.springframework-security}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${org.springframework-security}</version>
</dependency>
<!-- taglibs -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${org.springframework-security}</version>
</dependency>

servlet-context
<!-- 컨트롤러따로안만들고, 화면시나리오 -->
<view-controller path="/home/main"/>
<view-controller path="/member/main"/>
<view-controller path="/manager/main"/>
<view-controller path="/admin/main"/>
시나리오:
홈메인페이지는 로그인만하면가능
멤버메인은 롤유저가
매니저는 롤매니저
어드민은 롤어드민이라는 권한이있어야 사용할수잇음

이렇게
패스만 적고 뷰네임 안적은이유: 저 경로랑 똑같이 네임줄거니까 안적어도됨

<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<h1>Home 메인 화면입니다.</h1>
<br/>
<a href="<c:url value='/'/>">[/index로 가기]</a>
</body>
</html>
페이지별로 다 만들기
각각의 유알엘페이지로 넘길수잇는 index.jsp만들거임 ( views 바로밑에)
그 전에 index.jsp열리도록 viewcontroller (서블릿컨텍스트에)
<view-controller path="/" view-name="index"/>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<ul>
<li><a href="<c:url value='/home/main'/>">/home/main</a></li>
<li><a href="<c:url value='/member/main'/>">/member/main</a></li>
<li><a href="<c:url value='/manager/main'/>">/manager/main</a></li>
<li><a href="<c:url value='/admin/main'/>">/admin/main</a></li>
</ul>
</body>
</html>
web.xml에 필터를 거는것부터 시작
<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>
바로오류터짐

빈형성시켜주러


둘의 차이
계정정보를 우리가 주겠다
디비에서 끌고오겟다
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user" password="user" authorities="ROLE-USER"/>
<user name="manager" password="manager" authorities="ROLE-MANAGER"/>
<user name="admin" password="admin" authorities="ROLE-ADMIN"/>
</user-service>
</authentication-provider>
</authentication-manager>
사용자 지정을 한거임
여기까지가 인증에 대한 규정임
인증시 저기에잇는사람들 아니면 인증이되지않음. 즉 어플리케이션사용할수없다
그럼
인허가에 대한 부분은
결국 권한과 url에 대한 매핑정보가 될거임
이 패턴에 대해서는 이거에 대한 권할을 가지고잇을떄만 허가하겟다
매니저로 시작되는 url은 롤 매니저가있어야한다..
isAuthenticated : 인증이 된 상태 즉 로그인만되면 도니다.
/** 은 필터를 거치긴하겠지만 승인한다
범위가 좁을수록 우선순위가 높음
디폴트로그인화면이랑 로그아웃을 쓰기싫으면... 어쩌구해라
root-context에 해당 시큐리티 context 임포트해야함
<import resource="./security-context.xml"/>
필터로딩될떄 프록시가 로딩됨. 이떄 최초한번세팅을 하고 그후 요청올떄마다 거친다..

필터로딩시만들어지는애들이아님 이떄는 컨피그들이 있는지만 확인하는거임
최초요청이오면 한번세팅을 하고,
그후요청부터 세팅된상태로 계속하는거임
그리고
이닛쪽에서는 필터로딩시 서비스를 가져올수없음


index.jsp
<a href="/security/spring_security_Login">로그인</a>
<a href="/security/commons/j_spring_security_logout">로그아웃</a>
이거 왜추가하는거임/??
승계권한이 아니고 다 독립된거라
<user name="admin" password="admin" authorities="ROLE-ADMIN"/>
이걸
<user name="admin" password="admin" authorities="ROLE-ADMIN,ROLE_MANAGER,ROLE_USER"/>
이렇게 바꿔야 다 들어갈수잇음
교차가 ㄱ안되는 부분은 <역할>에 대한 권한 주기 가능
하지만 교차되는 부분들은 시스템권한으로 따로뺴야함
교착되는 권한들을 역할주면안되고, 시스템권한으로 다 뺴야함
그렇게 안하면 모든 관리자가 운영자의 뭔가에 간섭할수있게된다든가 해버림..
관리자는 어플리케이션의 모~든걸 관리감독하는걸 말함
대부분 유지보수업체나 그런사람들임..
커스터마이징할거임
일단 로그인화면부터 바꾸자
서블릿컨택스트
로그인화면줄거임
denied페이지도 만들거임
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<h1>권한이 유효하지 않습니다.</h1>
<br/>
<a href="<c:url value='/'/>">[/index로 가기]</a>
</body>
</html>
로그인페이지
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<h1>로그인</h1>
<form action="loginPost" method="post">
아이디: <input type="text" name = "id"><br/>
패스워드: <input type="password" name="pwd" /> <br/>
<input type="submit" value="로그인"/>
</form>
</body>
</html>

권한이없어서 denied 되는 페이지는 사용자가 요청한 유알엘을 던지는게 아니라 이 accessDenied유알엘을 던짐
로그인 화면도 지정해줘야함
<form-login
login-page="/commons/login"
/>
얘도 로그인 해야될떄 유알엘을 저걸로 던짐
근데
인증이되지않고 어딜 들어갈떄 로그인화면이 필요함
그때 저 유알엘 던지기시작함

근데 시큐리티가 언제 로그인화면을 내보내냐면
로그인안한상태에서

로그인이필요하니까 로그인화면을 서블릿에게 던짐!
이떄 commons.login이 넘어간다는 얘기임
그 유알에릉ㄹ
<form-login
login-page="/commons/login"
/>
ㅇㅕ기다가 준거임


어디를 가려고햇다가 잡힌거면로긴하고 거기로보내면되는데
그냥로그인만햇다면 어디로가야할지?
그게 디폴트url임


<logout logout-url="/commons/logout"
logout-success-url="/" />


>jdbc 서비스 써야함
data-source-ref : 얘가 직접 디비에 가게끔 하겟다
dao는 못쓰지만 데이터소스를 받을수는잇다. > datasource-context만들어야함
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource"
p:driverClassName="oracle.jdbc.driver.OracleDriver"
p:url="jdbc:oracle:thin:@localhost:1521:xe"
p:username="JSP"
p:password="java"
/>
</beans>
'
<!-- https://mvnrepository.com/artifact/oracle/ojdbc6 -->
<dependency>
<groupId>oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${oracle.ojdbc-version}</version>
</dependency>
<!-- commons-dbcp2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>${commons.dbcp2-version}</version>
</dependency>





권한에대한값은 이미 테이블에 authority가 있으므로
users-by-username-query="select id as username, pwd as password, enabled from member where id=?"
authorities-by-username-query="select id as username,authority from member where id=?"
이제 mimi로 로그인 가능하다
이제 화면단
index
로그인안햇으면 로그인만보여주고
로그인햇으면 로그아웃만 보여주기
->taglib 이용
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<sec:authorize access="!isAuthenticated()">
<a href="/security/commons/login">로그인</a>
</sec:authorize>
<sec:authorize access="isAuthenticated()">
<a href="/security/commons/logout">로그아웃</a>
</sec:authorize>
!is~니까 로그인안했을때!
권한이없으면 메뉴도 안보이게
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<ul>
<sec:authorize access="isAuthenticated()">
<li><a href="<c:url value='/home/main'/>">/home/main</a></li>
</sec:authorize>
<sec:authorize access="hasAuthority('ROLE_USER')">
<li><a href="<c:url value='/member/main'/>">/member/main</a></li>
</sec:authorize>
<sec:authorize access="hasAuthority('ROLE_MANAGER')">
<li><a href="<c:url value='/manager/main'/>">/manager/main</a></li>
</sec:authorize>
<sec:authorize access="hasAuthority('ROLE_ADMIN')">
<li><a href="<c:url value='/admin/main'/>">/admin/main</a></li>
</sec:authorize>
</ul>
<sec:authorize access="!isAuthenticated()">
<a href="/security/commons/login">로그인</a>
</sec:authorize>
<sec:authorize access="isAuthenticated()">
<a href="/security/commons/logout">로그아웃</a>
</sec:authorize>
</body>
</html>
첨에 로그임ㄴ밖에 안보임
로그인하면 인덱스로오고
권한에따라 메뉴가 달리보임