카테고리 없음

0315 스프링 시큐리티 모듈

unemo 2021. 3. 15. 10:09
반응형

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>
	&nbsp;&nbsp;&nbsp;
	<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"
	/>

ㅇㅕ기다가 준거임

 

얘한테 id, pwd라는 파라미터로 간다는걸알려줘야함

 

어디를 가려고햇다가 잡힌거면로긴하고 거기로보내면되는데

그냥로그인만햇다면 어디로가야할지?

 

그게 디폴트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>

 

 

 

 

 

? 와일드카드는 preparestatment쓴다는말임

권한에대한값은 이미 테이블에 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>

 

첨에 로그임ㄴ밖에 안보임

로그인하면 인덱스로오고

권한에따라 메뉴가 달리보임

 

 

반응형