Zugriffskontrolle (SSO,JWT,SAML,XACML)

From
Revision as of 17:11, 16 September 2018 by Stepo (talk | contribs)
Jump to navigation Jump to search

Einleitung

Zugriffskontrolle ( engl. access control ) soll die Authentizität (Wer ist das?) und Autorisierung (Darf der das?) von Nutzern bei Zugriff auf Ressourcen sicher stellen.

Single Sign On (SSO)

Durch die Proliferation von gemeinen Haushaltsgeräten mit integriertem Computer (umg. IoT-Geräte) ist die herkömmliche Zugriffskontrolle per Login- und Passwortabfrage unpraktisch. Das Ziel von Single Sign On soll dieses Problem lösen, indem Identitäten zentral verwaltet werden und diese genutzt werden kann um sich überall an- und abzumelden.

SAML/XACML

Json Web Token (JWT)

JSON Web Token sind ein kompaktes, URL-kodierbares Nachrichtenformat, welches zum Ziel hat "Claims" zu sicher zu übertragen. "Sicher" bedeutet hier, dass entweder nur die Integrität als auch die Integrität und Vertraulichkeit geschützt werden kann. Hauptsächlich liegt der Augenmerk laut homepage jedoch auch der Integrität.

Ein JWT besteht aus drei Teilen: BASE64URL kodierten Header, getrennt mit Punkt vom BASE64URL kodierten Payload und der BASE64URL kodierten Signatur. Diese Signatur besteht aus der konkatentation von Header und Payload.

Beispiel JWT

Header mit Signatur- oder Verschlüsselungsalgorithmus (hier HMAC SHA256) und dem Typ des Tokens (hier JWT)

{
 "alg": "HS256",
 "typ": "JWT"
}

Payload besteht hier aus Subject, Name und Issued At Zeitstempel:

{
 "sub": "1234567890",
 "name": "John Doe",
 "iat": 1516239022
}

Signatur besteht aus:

HMACSHA256(
 base64UrlEncode(header) + "." +
 base64UrlEncode(payload),
 Passw0rt1234
)

Dies generiert das Token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
WetwNp0BkAboJQMpyRPNJ2MiVw5Af-Iyt3mU1DX_GiY

Minimum Working Example

In einem minimum working example soll das Zusammenspiel der im Artikel besprochenen Elemente vergegenwärtigt werden. Die Architektur basiert auf der vorgestellten SAML-XACML Architektur, wobei nur der Policy Decicision Point, die Policy Enforcement Points und der Identity Provider implementiert werden. Zusätzlich wurden der SAML Prozess durch einen JWT-basierten Tokenaustausch ersetzt. Der Messageaustausch geschieht durch HTTP REST.

Setup

1. Code laden von github

2. Requirements laut Readme.md installieren

Beispielablauf eines Servicerequests

Access control example sequence.png

JWT holen

POST gegen den Registrierungsendpunkt oder Loginendpunkt des IDP:

POST /login HTTP/1.1
Host: 127.0.0.1:3000
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache

username=stepo&password=stepo

Antwort mit Json Web Token im Payload:

HTTP/1.1 200
status: 200
content-type: application/json
content-length: 610

{"message": "Logged in as stepo", "access_token": 
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MzcwOTcxNTYsIm5iZiI6MTUzNzA5NzE1NiwianRpIjoi
NGI1ZjY2M2ItNTRkMi00NzY2LTkxOWUtNThlZjdhZGUxZDljIiwiZXhwIjoxNTM3MDk4MDU2LCJpZGVudGl0eSI6InN0ZX
BvIiwiZnJlc2giOmZhbHNlLCJ0eXBlIjoiYWNjZXNzIn0.QCtGHX4odS5togFgnJnPlNWfum5SWJkud2yXwA_xnE4", 
"refresh_token":  "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MzcwOTcxNTYsIm5iZiI6MTUzNz
A5NzE1NiwianRpIjoiNGYwODgwOTEtOThjMi00MWVhLWFmZmUtN2U1N2JlYTY5MjU2IiwiZXhwIjoxNTM5Njg5MTU2LCJp
ZGVudGl0eSI6InN0ZXBvIiwidHlwZSI6InJlZnJlc2gifQ.H9SqGRcY5RKla23jcp_lNUUflsfepHCfbkPaahGxTSU"}

Service Anfragen mit JWT

POST gegen Serviceendpunkt:

POST /protected_toaster HTTP/1.1
Host: 127.0.0.1:4000
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MzcwOTY2NjksIm5iZiI6MTU
zNzA5NjY2OSwianRpIjoiZmZhNDlmZGMtMTJhNC00OTk1LTk5NjctMmVkOTc2NDUyNzM3IiwiZXhwIjoxNTM3MDk3NTY5L
CJpZGVudGl0eSI6InN0ZXBvIiwiZnJlc2giOmZhbHNlLCJ0eXBlIjoiYWNjZXNzIn0.egBiDeU2IC4hb7hBoUVGkAbo-c4
_UYCrisAJreLVIuM
Cache-Control: no-cache

Serviceendpunkt schickt POST gegen Policy Decision Point für eine Autorisierung:

POST /services/pdp HTTP/1.1
Host: localhost:10000
Content-Type: application/xacml+json
Cache-Control: no-cache

{"Request":{"ReturnPolicyIdList":false,"CombinedDecision":false,"Category":[
  {"CategoryId":"urn:oasis:names:tc:xacml:1.0:subject-category:access-subject","Attribute":[{"IncludeInResult":false,"AttributeId":"urn:oasis:names:tc:xacml:1.0:subject:subject-id","DataType":"http://www.w3.org /2001/XMLSchema#string","Value":[
      "stepo"
    ]}]}
  ,{"CategoryId":"urn:oasis:names:tc:xacml:3.0:attribute-category:resource","Attribute":[{"IncludeInResult":false,"AttributeId":"urn:oasis:names:tc:xacml:1.0:resource:resource-id","DataType":"http://www.w3.org /2001/XMLSchema#anyURI","Value":[
      "protected_toaster"
    ]}]}
  ,{"CategoryId":"urn:oasis:names:tc:xacml:3.0:attribute-category:action","Attribute":[{"IncludeInResult":false,"AttributeId":"urn:oasis:names:tc:xacml:1.0:action:action-id","DataType":"http://www.w3.org /2001/XMLSchema#string","Value":[
      "post"
    ]}]}
  ,{"CategoryId":"urn:oasis:names:tc:xacml:3.0:attribute-category:environment","Attribute":[]}
]}}

Der Policy Decision Point überprüft seine Datenbank nach der XACML Regel für diesen User und Endpunkt:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" PolicyId="urn:oasis:names:tc:xacml:2.0:conformance-test:IIA1:policy" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides" Version="1.0">
    <Description>
        Policy for Conformance Test IIA001.
    </Description>
    <Target/>
    <Rule Effect="Permit" RuleId="urn:oasis:names:tc:xacml:2.0:conformance-test:IIA1:rule">
        <Description>
            stepo can post to green and red resource
        </Description>
        <Target>
            <AnyOf>
                <AllOf>
                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">stepo</AttributeValue>
                        <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
                    </Match>
                </AllOf>
            </AnyOf>
            <AnyOf>
                <AllOf>
                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal">
                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">protected_toaster</AttributeValue>
                        <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#anyURI"  MustBePresent="false"/>
                    </Match>
                </AllOf>
                <AllOf>
                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal">
                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">protected_tv</AttributeValue>
                        <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="false"/>
                    </Match>
                </AllOf>
            </AnyOf>
            <AnyOf>
                <AllOf>
                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">post</AttributeValue>
                        <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
                   </Match>
                </AllOf>
            </AnyOf>
        </Target>
    </Rule>
</Policy>

Da die Anfrage eine Regel findet wird autorisiert mit:

HTTP/1.1 200
status: 200
date: Sun, 16 Sep 2018 11:38:31 GMT
content-type: application/json
transfer-encoding: chunked

{"Response":[{"Decision":"Permit"}]}


Der Serviceendpunkt antwortet an den Konsumenten final:

HTTP/1.1 200
status: 200
content-type: application/json
content-length: 23

{"message": "success"}