[ Architecture, Technology ,Web ] SSO(Single Sign On) 그리고 SAML에 대해

이미지
이번 프로젝트 내부에서 어쩌다보니  유저 인증 관련 업무를 담당하게 되었고, 해야하는 업무는 내부에 사용했던 적이 없던  새로운 개발 플랫폼에서  SSO의 프로토콜 중  SAML을 이용해 앱의 인증을 구현해야만 했다. SSO를 생각해본적 조차 없는 상황에 이를 새로운 개발 플랫폼에 도입해야 했기 때문에 많은 시행착오를 겪었으나 구현에 성공하였으며 덕분에 SSO에 대한 전반적인 지식을 쌓을 수 있었다. 이번에는 그러한 과정에서 나온 지식들과 경험을  공유하고자 한다. SSO에 대한 정의 먼저 사전적 정의 부터 살펴보자. 다만, 기술적인 용어다보니 자주 사용하는 옥스포드 사전에 정의를 찾을 수 없기 때문에  검색으로 찾을 수 있는 정의를 몇 가지 살펴보고 교차 검증을 해보자. 첫 번째 정의를 살펴보자. Single sign-on (SSO) is an identification method that enables users to log in to multiple applications and websites with one set of credentials.  SSO는 웹사이트에서 한 번의 인증(one set of credentials)으로 복수의 어플리케이션에 로그인 할 수 있는 인증(identification) 방법(method) 이다. 두 번째는 위키피디아의 정의이다. Single sign-on (SSO) is an authentication scheme that allows a user to log in with a single ID to any of several related, yet independent, software systems. SSO는 독립적이지만 연관되어있는 몇몇 소프트웨어에 대해 하나의 ID로 로그인을 할 수 있도록 하는 인증 구조(scheme) 세부 설명에 조금 차이가 있어 보이지만 전체적인 틀은 매우 비슷해 보인다.  몇 가지 포인트가 되는 단어를 추출해 이를 연결해보자면 아래와 같은 의미를 산출 할 수 있다. 독립적이지만 연관되어 있

[ Django, Python ] mozilla 튜토리얼 예제로 살펴보는 Django 분석 ⑦ - 3 : listing the current user's books(사용자의 책 목록)

다음으로 
현재 인증되어진 사용자가 빌린 책을 보는 
기능을 작성해보자.

물론 지금 책을 대출하는 기능은 없기 때문에
Django 관리자 페이지에서 데이터를 입력 해주어야 한다.

①Model


catalog/ 경로에 models.py 파일을 열어


from django.contrib.auth.models import User
borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
위와 같이 Django 인증 관련 Model인 User를 import하고
Class 기반 BookInstance Model에 borrower 필드를 추가하자.


from datetime import date
@property
def is_overdue(self):
    if self.due_back and date.today() > self.due_back:
        return True
    return False
또한 date 관련 처리를 하기 위해 
datetime 객체를 import하고

반납 기간이 지났는지를 확인하는 함수인 
is_overdue라는 함수를 작성해보자.

python3 manage.py makemigrations
python3 manage.py migrate

마지막으로 Model을 수정했기 때문에 
다시 한번 마이그레이션 해주자.

②관리자 페이지(Admin)


관리자 페이지에 새로운 필드를 표시하기 위해 


@admin.register(BookInstance)
class BookInstanceAdmin(admin.ModelAdmin):
    list_display = ('book', 'status', 'borrower', 'due_back', 'id')
    list_filter = ('status', 'due_back')
    
    fieldsets = (
        (None, {
            'fields': ('book','imprint', 'id')
        }),
        ('Availability', {
            'fields': ('status', 'due_back','borrower')
        }),
    )
위와 같이 catalog/ 경로의 admin.py 파일에 
borrower 필드를 추가 한다.

관리지 페이지에 들어가보면
BORROWER 필드가 화면에 표시됨을 알 수 있고,

나는 librarian1이라는 유저에게 두 책을 빌려주었다.

③ 대출(On loan) View


다음으로 현재 사용자가 대출하고 있는 
도서 목록을 가져오는 View를 추가해보자.


from django.contrib.auth.mixins import LoginRequiredMixin

class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView):
    """Generic class-based view listing books on loan to current user."""
    model = BookInstance
    template_name ='catalog/bookinstance_list_borrowed_user.html'
    paginate_by = 10
    
    def get_queryset(self):
        return BookInstance.objects.filter(borrower=self.request.user).filter(status__exact='o').order_by('due_back')
위와 같이 클래스 매개변수로서 LoginRequiredMixin을 
설정했기 때문에 로그인한 사용자
즉, 인증된 사용자만 이 View를 불러올 수 있다.

template_name을 default값이 아닌
사용하지 않고 설정해주었고,

QuerySet을 현재 인증된 사용자로 제한하기 위한 필터
(borrower=self.request.user)
status 필드의 데이터가 'o'와 일치하는 것을 찾는 필터를 추가
(filter(status__exact='o'))
그리고 due_back 필드의 데이터를 내림 차순으로 정렬한 값을 
(order_by('due_back'))
즉, 가장 오래된 날짜부터 정렬 한 값을 리턴하게 코딩했다.

④ 대출 도서에 대한 URLconf


이제 URL을 추가하자.


urlpatterns += [   
    path('mybooks/', views.LoanedBooksByUserListView.as_view(), name='my-borrowed'),
]
위와 같이 locallibrary/catalog/ 경로
urls.py 파일에 코드를 추가 하자.

⑤ 대출 도서 Template


대출 도서를 나타내는 템플릿을 추가해보자.


{% extends "base_generic.html" %}

{% block content %}
    <h1>Borrowed books</h1>

    {% if bookinstance_list %}
    <ul>

      {% for bookinst in bookinstance_list %} 
      <li class="{% if bookinst.is_overdue %}text-danger{% endif %}">
        <a href="{% url 'book-detail' bookinst.book.pk %}">{{bookinst.book.title}}</a> ({{ bookinst.due_back }})        
      </li>
      {% endfor %}
    </ul>

    {% else %}
      <p>There are no books borrowed.</p>
    {% endif %}       
{% endblock %}
/catalog/templates/catalog/ 경로에 
bookinstance_list_borrowed_user.html 파일을 추가하고
위와 같은 코드를 추가 하자.

추가 한 후 에
http://127.0.0.1:8000/catalog/mybooks/페이지에 들어가면 
빌린 목록을 포함한 연체・비 연체 목록도 알수 있다.

⑥ 사이드 바(Side Bar)에 목록 추가


마지막으로 사이드 바에 
빌린 책의 목록을 볼 수 있도록 추가해보자.

/locallibrary/catalog/templates/ 경로의 
base_generic.html 파일에 


 <ul class="sidebar-nav">
   {% if user.is_authenticated %}
   <li>User: {{ user.get_username }}</li>
   <li><a href="{% url 'my-borrowed' %}">My Borrowed</a></li>
   <li><a href="{% url 'logout'%}?next={{request.path}}">Logout</a></li>   
   {% else %}
   <li><a href="{% url 'login'%}?next={{request.path}}">Login</a></li>   
   {% endif %} 
 </ul>
위와 같이 코드를 추가하자.


에러가 없다면 위와 같이
사이드 바에 빨간색 박스와 같이 
빌린 목록을 볼 수 있는 하이퍼 링크가 추가될 것이다.


이 블로그의 인기 게시물

[ Web ] 웹 애플리케이션 아키텍처 (Web Application Architecture)

[ Web ] 서버 사이드(Sever Side) ? 클라이언트 사이드(Client Side)? 1 [서론, 클라이언트 사이드(Client Side)]

[ Web ] 웹 애플리케이션? 웹 사이트?(Web Application? Web Site?)