From 0e10ed0e0b6060910b6f65844a78d5e470c3b4fd Mon Sep 17 00:00:00 2001 From: Stefan Benz <46600784+stebenz@users.noreply.github.com> Date: Wed, 26 Mar 2025 18:08:13 +0100 Subject: [PATCH] fix: SAML and OIDC issuer (in proxied use cases) (#9638) # Which Problems Are Solved When using implicit flow through the session API and a login UI on a custom domain (proxy), the tokens were signed by the API domain of the instance, rather than the public (proxy) domain. The SAML response had the same issue. Additionally, the saml library had an issue and lost the issuer context. This prevented also a successful login through the hosted login UI. # How the Problems Are Solved - The issuer of the SAML and Auth request is persisted to provide the information when signing the responses and tokens. - The SAML library is updated to the latest version. # Additional Changes None # Additional Context None --- go.mod | 2 +- go.sum | 54 ++----- internal/api/grpc/oidc/v2/oidc.go | 8 +- internal/api/grpc/saml/v2/saml.go | 7 + internal/api/oidc/auth_request.go | 1 + internal/api/oidc/op.go | 12 +- internal/api/saml/auth_request.go | 9 +- internal/api/saml/provider.go | 3 + internal/api/saml/storage.go | 18 ++- internal/command/auth_request.go | 3 + internal/command/auth_request_model.go | 2 + internal/command/auth_request_test.go | 22 +++ internal/command/oidc_session_test.go | 7 + internal/command/saml_request.go | 35 +++-- internal/command/saml_request_model.go | 18 ++- internal/command/saml_request_test.go | 145 ++++++++++-------- internal/command/saml_session_test.go | 4 + .../repository/authrequest/auth_request.go | 3 + .../repository/samlrequest/saml_request.go | 35 +++-- 19 files changed, 226 insertions(+), 162 deletions(-) diff --git a/go.mod b/go.mod index 74190154df..b27972938e 100644 --- a/go.mod +++ b/go.mod @@ -73,7 +73,7 @@ require ( github.com/zitadel/logging v0.6.2 github.com/zitadel/oidc/v3 v3.36.1 github.com/zitadel/passwap v0.7.0 - github.com/zitadel/saml v0.3.4 + github.com/zitadel/saml v0.3.5 github.com/zitadel/schema v1.3.1 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 diff --git a/go.sum b/go.sum index 9c8f5df72e..5450c57b3d 100644 --- a/go.sum +++ b/go.sum @@ -260,6 +260,12 @@ github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvSc github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= +github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-redis/redis/v7 v7.4.1 h1:PASvf36gyUpr2zdOUS/9Zqc80GbM+9BDyiJSJDDOrTI= +github.com/go-redis/redis/v7 v7.4.1/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-redsync/redsync/v4 v4.13.0 h1:49X6GJfnbLGaIpBBREM/zA4uIMDXKAh1NDkvQ1EkZKA= github.com/go-redsync/redsync/v4 v4.13.0/go.mod h1:HMW4Q224GZQz6x1Xc7040Yfgacukdzu7ifTDAKiyErQ= github.com/go-sourcemap/sourcemap v2.1.4+incompatible h1:a+iTbH5auLKxaNwQFg0B+TCYl6lbukKPc7b5x0n1s6Q= @@ -324,6 +330,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws= +github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -437,8 +445,6 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI= -github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ= github.com/jackc/pgx/v5 v5.7.3 h1:PO1wNKj/bTAwxSJnO1Z4Ai8j4magtqg2SLNjEDzcXQo= github.com/jackc/pgx/v5 v5.7.3/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= @@ -507,6 +513,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= @@ -604,8 +612,6 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pashagolub/pgxmock/v4 v4.3.0 h1:DqT7fk0OCK6H0GvqtcMsLpv8cIwWqdxWgfZNLeHCb/s= -github.com/pashagolub/pgxmock/v4 v4.3.0/go.mod h1:9VoVHXwS3XR/yPtKGzwQvwZX1kzGB9sM8SviDcHDa3A= github.com/pashagolub/pgxmock/v4 v4.6.0 h1:ds0hIs+bJtkfo01vqjp0BOFirjt4Ea8XV082uorzM3w= github.com/pashagolub/pgxmock/v4 v4.6.0/go.mod h1:9VoVHXwS3XR/yPtKGzwQvwZX1kzGB9sM8SviDcHDa3A= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= @@ -633,8 +639,6 @@ github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -650,8 +654,6 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -667,6 +669,8 @@ github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Ung github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM= github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA= +github.com/redis/rueidis v1.0.19 h1:s65oWtotzlIFN8eMPhyYwxlwLR1lUdhza2KtWprKYSo= +github.com/redis/rueidis v1.0.19/go.mod h1:8B+r5wdnjwK3lTFml5VtxjzGOQAC+5UmujoD12pDrEo= github.com/riverqueue/river v0.19.0 h1:WRh/NXhp+WEEY0HpCYgr4wSRllugYBt30HtyQ3jlz08= github.com/riverqueue/river v0.19.0/go.mod h1:YJ7LA2uBdqFHQJzKyYc+X6S04KJeiwsS1yU5a1rynlk= github.com/riverqueue/river/riverdriver v0.19.0 h1:NyHz5DfB13paT2lvaO0CKmwy4SFLbA7n6MFRGRtwii4= @@ -717,8 +721,6 @@ github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIK github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/sony/gobreaker/v2 v2.0.0 h1:23AaR4JQ65y4rz8JWMzgXw2gKOykZ/qfqYunll4OwJ4= -github.com/sony/gobreaker/v2 v2.0.0/go.mod h1:8JnRUz80DJ1/ne8M8v7nmTs2713i58nIt4s7XcGe/DI= github.com/sony/gobreaker/v2 v2.1.0 h1:av2BnjtRmVPWBvy5gSFPytm1J8BmN5AGhq875FfGKDM= github.com/sony/gobreaker/v2 v2.1.0/go.mod h1:dO3Q/nCzxZj6ICjH6J/gM0r4oAwBMVLY8YAQf+NTtUg= github.com/sony/sonyflake v1.2.0 h1:Pfr3A+ejSg+0SPqpoAmQgEtNDAhc2G1SUYk205qVMLQ= @@ -755,6 +757,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203 h1:QVqDTf3h2WHt08YuiTGPZLls0Wq99X9bWd0Q5ZSBesM= +github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203/go.mod h1:oqN97ltKNihBbwlX8dLpwxCl3+HnXKV/R0e+sRLd9C8= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -772,8 +776,6 @@ github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 h1:5u+EJUQiosu3JFX0 github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2/go.mod h1:4kyMkleCiLkgY6z8gK5BkI01ChBtxR0ro3I1ZDcGM3w= github.com/ttacon/libphonenumber v1.2.1 h1:fzOfY5zUADkCkbIafAed11gL1sW+bJ26p6zWLBMElR4= github.com/ttacon/libphonenumber v1.2.1/go.mod h1:E0TpmdVMq5dyVlQ7oenAkhsLu86OkUl+yR4OAxyEg/M= -github.com/twilio/twilio-go v1.22.2 h1:LUz6OTWKY4/oW4e+O2ah2JMq03gJvGu6bxaF0Y7l+Xc= -github.com/twilio/twilio-go v1.22.2/go.mod h1:zRkMjudW7v7MqQ3cWNZmSoZJ7EBjPZ4OpNh2zm7Q6ko= github.com/twilio/twilio-go v1.24.1 h1:bpBL1j5GRdJGSG+tCdo0O94BwK4uDOHQuNT5ndzljPg= github.com/twilio/twilio-go v1.24.1/go.mod h1:zRkMjudW7v7MqQ3cWNZmSoZJ7EBjPZ4OpNh2zm7Q6ko= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= @@ -803,8 +805,8 @@ github.com/zitadel/oidc/v3 v3.36.1 h1:1AT1NqKKEqAwx4GmKJZ9fYkWH2WIn/VKMfQ46nBtRf github.com/zitadel/oidc/v3 v3.36.1/go.mod h1:dApGZLvWZTHRuxmcbQlW5d2XVjVYR3vGOdq536igmTs= github.com/zitadel/passwap v0.7.0 h1:TQTr9TV75PLATGICor1g5hZDRNHRvB9t0Hn4XkiR7xQ= github.com/zitadel/passwap v0.7.0/go.mod h1:/NakQNYahdU+YFEitVD6mlm8BLfkiIT+IM5wgClRoAY= -github.com/zitadel/saml v0.3.4 h1:L2pybnx2Hs+kqebZmUbnZUd9L/CY2sNw5psMWw2D/6Q= -github.com/zitadel/saml v0.3.4/go.mod h1:M0losAULJpLtAmXrYqBnf375ia2rMgJ75b1mpaU/GlA= +github.com/zitadel/saml v0.3.5 h1:L1RKWS5y66cGepVxUGjx/WSBOtrtSpRA/J3nn5BJLOY= +github.com/zitadel/saml v0.3.5/go.mod h1:ybs3e4tIWdYgSYBpuCsvf3T4FNDfbXYM+GPv5vIpHYk= github.com/zitadel/schema v1.3.1 h1:QT3kwiRIRXXLVAs6gCK/u044WmUVh6IlbLXUsn6yRQU= github.com/zitadel/schema v1.3.1/go.mod h1:071u7D2LQacy1HAN+YnMd/mx1qVE2isb0Mjeqg46xnU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -816,54 +818,30 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/detectors/gcp v1.34.0 h1:JRxssobiPg23otYU5SbWtQC//snGVIM3Tx6QRzlQBao= go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= -go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= -go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo= -go.opentelemetry.io/otel/exporters/prometheus v0.50.0 h1:2Ewsda6hejmbhGFyUvWZjUThC98Cf8Zy6g0zkIimOng= -go.opentelemetry.io/otel/exporters/prometheus v0.50.0/go.mod h1:pMm5PkUo5YwbLiuEf7t2xg4wbP0/eSJrMxIMxKosynY= go.opentelemetry.io/otel/exporters/prometheus v0.57.0 h1:AHh/lAP1BHrY5gBwk8ncc25FXWm/gmmY3BX258z5nuk= go.opentelemetry.io/otel/exporters/prometheus v0.57.0/go.mod h1:QpFWz1QxqevfjwzYdbMb4Y1NnlJvqSGwyuU0B4iuc9c= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0 h1:WDdP9acbMYjbKIyJUhTvtzj601sVJOqgWdUxSdR/Ysc= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zbNIONBLPwvFnwNHGj4zge8uTCM/UPIVW1Mq2I= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.29.0 h1:X3ZjNp36/WlkSYx0ul2jw4PtbNEDDeLskw3VPsrpYM0= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.29.0/go.mod h1:2uL/xnOXh0CHOBFCWXz5u1A4GXLiW+0IQIzVbeOEQ0U= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0 h1:T0Ec2E+3YZf5bgTNQVet8iTDW7oIk03tXHq+wkwIDnE= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.35.0/go.mod h1:30v2gqH+vYGJsesLWFov8u47EpYTcIQcBjKpI6pJThg= -go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= -go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= -go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= -go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= -go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= -go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= -go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= -go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= diff --git a/internal/api/grpc/oidc/v2/oidc.go b/internal/api/grpc/oidc/v2/oidc.go index 73fc995be2..8612d11558 100644 --- a/internal/api/grpc/oidc/v2/oidc.go +++ b/internal/api/grpc/oidc/v2/oidc.go @@ -10,7 +10,7 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" "github.com/zitadel/zitadel/internal/api/grpc/object/v2" - "github.com/zitadel/zitadel/internal/api/http" + http_utils "github.com/zitadel/zitadel/internal/api/http" "github.com/zitadel/zitadel/internal/api/oidc" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/query" @@ -158,7 +158,11 @@ func (s *Server) linkSessionToAuthRequest(ctx context.Context, authRequestID str return nil, err } authReq := &oidc.AuthRequestV2{CurrentAuthRequest: aar} - ctx = op.ContextWithIssuer(ctx, http.DomainContext(ctx).Origin()) + issuer := authReq.Issuer + if issuer == "" { + issuer = http_utils.DomainContext(ctx).Origin() + } + ctx = op.ContextWithIssuer(ctx, issuer) var callback string if aar.ResponseType == domain.OIDCResponseTypeCode { callback, err = oidc.CreateCodeCallbackURL(ctx, authReq, s.op.Provider()) diff --git a/internal/api/grpc/saml/v2/saml.go b/internal/api/grpc/saml/v2/saml.go index 866846dfd7..43eae5feb1 100644 --- a/internal/api/grpc/saml/v2/saml.go +++ b/internal/api/grpc/saml/v2/saml.go @@ -4,9 +4,11 @@ import ( "context" "github.com/zitadel/logging" + "github.com/zitadel/saml/pkg/provider" "google.golang.org/protobuf/types/known/timestamppb" "github.com/zitadel/zitadel/internal/api/grpc/object/v2" + http_utils "github.com/zitadel/zitadel/internal/api/http" "github.com/zitadel/zitadel/internal/api/saml" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/query" @@ -76,6 +78,11 @@ func (s *Server) linkSessionToSAMLRequest(ctx context.Context, samlRequestID str return nil, err } authReq := &saml.AuthRequestV2{CurrentSAMLRequest: aar} + responseIssuer := authReq.ResponseIssuer + if responseIssuer == "" { + responseIssuer = http_utils.DomainContext(ctx).Origin() + } + ctx = provider.ContextWithIssuer(ctx, responseIssuer) url, body, err := s.idp.CreateResponse(ctx, authReq) if err != nil { return nil, err diff --git a/internal/api/oidc/auth_request.go b/internal/api/oidc/auth_request.go index d433603cd8..a113392df8 100644 --- a/internal/api/oidc/auth_request.go +++ b/internal/api/oidc/auth_request.go @@ -111,6 +111,7 @@ func (o *OPStorage) createAuthRequestLoginClient(ctx context.Context, req *oidc. Prompt: PromptToBusiness(req.Prompt), UILocales: UILocalesToBusiness(req.UILocales), MaxAge: MaxAgeToBusiness(req.MaxAge), + Issuer: o.contextToIssuer(ctx), } if req.LoginHint != "" { authRequest.LoginHint = &req.LoginHint diff --git a/internal/api/oidc/op.go b/internal/api/oidc/op.go index 153a13f06e..37a9ba2bce 100644 --- a/internal/api/oidc/op.go +++ b/internal/api/oidc/op.go @@ -75,6 +75,7 @@ type OPStorage struct { encAlg crypto.EncryptionAlgorithm locker crdb.Locker assetAPIPrefix func(ctx context.Context) string + contextToIssuer func(context.Context) string } // Provider is used to overload certain [op.Provider] methods @@ -119,7 +120,7 @@ func NewServer( if err != nil { return nil, zerrors.ThrowInternal(err, "OIDC-EGrqd", "cannot create op config: %w") } - storage := newStorage(config, command, query, repo, encryptionAlg, es, projections) + storage := newStorage(config, command, query, repo, encryptionAlg, es, projections, ContextToIssuer) keyCache := newPublicKeyCache(ctx, config.PublicKeyCacheMaxAge, queryKeyFunc(query)) accessTokenKeySet := newOidcKeySet(keyCache, withKeyExpiryCheck(true)) idTokenHintKeySet := newOidcKeySet(keyCache) @@ -182,9 +183,13 @@ func NewServer( return server, nil } +func ContextToIssuer(ctx context.Context) string { + return http_utils.DomainContext(ctx).Origin() +} + func IssuerFromContext(_ bool) (op.IssuerFromRequest, error) { return func(r *http.Request) string { - return http_utils.DomainContext(r.Context()).Origin() + return ContextToIssuer(r.Context()) }, nil } @@ -220,7 +225,7 @@ func createOPConfig(config Config, defaultLogoutRedirectURI string, cryptoKey [] return opConfig, nil } -func newStorage(config Config, command *command.Commands, query *query.Queries, repo repository.Repository, encAlg crypto.EncryptionAlgorithm, es *eventstore.Eventstore, db *database.DB) *OPStorage { +func newStorage(config Config, command *command.Commands, query *query.Queries, repo repository.Repository, encAlg crypto.EncryptionAlgorithm, es *eventstore.Eventstore, db *database.DB, contextToIssuer func(context.Context) string) *OPStorage { return &OPStorage{ repo: repo, command: command, @@ -236,6 +241,7 @@ func newStorage(config Config, command *command.Commands, query *query.Queries, encAlg: encAlg, locker: crdb.NewLocker(db.DB, locksTable, signingKey), assetAPIPrefix: assets.AssetAPI(), + contextToIssuer: contextToIssuer, } } diff --git a/internal/api/saml/auth_request.go b/internal/api/saml/auth_request.go index f31647f705..db0c74a931 100644 --- a/internal/api/saml/auth_request.go +++ b/internal/api/saml/auth_request.go @@ -3,7 +3,6 @@ package saml import ( "context" "encoding/base64" - "net/http" "net/url" "github.com/zitadel/saml/pkg/provider" @@ -34,15 +33,9 @@ func (p *Provider) CreateResponse(ctx context.Context, authReq models.AuthReques AcsUrl: authReq.GetAccessConsumerServiceURL(), RequestID: authReq.GetAuthRequestID(), Audience: authReq.GetIssuer(), + Issuer: p.GetEntityID(ctx), } - issuer := ContextToIssuer(ctx) - req, err := http.NewRequestWithContext(provider.ContextWithIssuer(ctx, issuer), http.MethodGet, issuer, nil) - if err != nil { - return "", "", err - } - resp.Issuer = p.GetEntityID(req) - samlResponse, err := p.AuthCallbackResponse(ctx, authReq, resp) if err != nil { return "", "", err diff --git a/internal/api/saml/provider.go b/internal/api/saml/provider.go index 0b056797d5..428fc35ed9 100644 --- a/internal/api/saml/provider.go +++ b/internal/api/saml/provider.go @@ -60,6 +60,7 @@ func NewProvider( projections, fmt.Sprintf("%s%s?%s=", login.HandlerPrefix, login.EndpointLogin, login.QueryAuthRequestID), conf.DefaultLoginURLV2, + ContextToIssuer, ) if err != nil { return nil, err @@ -117,6 +118,7 @@ func newStorage( db *database.DB, defaultLoginURL string, defaultLoginURLV2 string, + contextToIssuer func(context.Context) string, ) (*Storage, error) { return &Storage{ encAlg: encAlg, @@ -128,6 +130,7 @@ func newStorage( query: query, defaultLoginURL: defaultLoginURL, defaultLoginURLv2: defaultLoginURLV2, + contextToIssuer: contextToIssuer, }, nil } diff --git a/internal/api/saml/storage.go b/internal/api/saml/storage.go index 834cc7b392..935e986c72 100644 --- a/internal/api/saml/storage.go +++ b/internal/api/saml/storage.go @@ -64,6 +64,7 @@ type Storage struct { defaultLoginURL string defaultLoginURLv2 string + contextToIssuer func(context.Context) string } func (p *Storage) GetEntityByID(ctx context.Context, entityID string) (*serviceprovider.ServiceProvider, error) { @@ -137,14 +138,15 @@ func (p *Storage) createAuthRequestLoginClient(ctx context.Context, req *samlp.A ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() samlRequest := &command.SAMLRequest{ - ApplicationID: applicationID, - ACSURL: acsUrl, - RelayState: relayState, - RequestID: req.Id, - Binding: protocolBinding, - Issuer: req.Issuer.Text, - Destination: req.Destination, - LoginClient: loginClient, + ApplicationID: applicationID, + ACSURL: acsUrl, + RelayState: relayState, + RequestID: req.Id, + Binding: protocolBinding, + Issuer: req.Issuer.Text, + Destination: req.Destination, + LoginClient: loginClient, + ResponseIssuer: p.contextToIssuer(ctx), } aar, err := p.command.AddSAMLRequest(ctx, samlRequest) diff --git a/internal/command/auth_request.go b/internal/command/auth_request.go index 340155d11b..d60012637a 100644 --- a/internal/command/auth_request.go +++ b/internal/command/auth_request.go @@ -29,6 +29,7 @@ type AuthRequest struct { LoginHint *string HintUserID *string NeedRefreshToken bool + Issuer string } type CurrentAuthRequest struct { @@ -73,6 +74,7 @@ func (c *Commands) AddAuthRequest(ctx context.Context, authRequest *AuthRequest) authRequest.LoginHint, authRequest.HintUserID, authRequest.NeedRefreshToken, + authRequest.Issuer, )) if err != nil { return nil, err @@ -180,6 +182,7 @@ func authRequestWriteModelToCurrentAuthRequest(writeModel *AuthRequestWriteModel MaxAge: writeModel.MaxAge, LoginHint: writeModel.LoginHint, HintUserID: writeModel.HintUserID, + Issuer: writeModel.Issuer, }, SessionID: writeModel.SessionID, UserID: writeModel.UserID, diff --git a/internal/command/auth_request_model.go b/internal/command/auth_request_model.go index a6766d1979..0e8d88fd13 100644 --- a/internal/command/auth_request_model.go +++ b/internal/command/auth_request_model.go @@ -36,6 +36,7 @@ type AuthRequestWriteModel struct { AuthMethods []domain.UserAuthMethodType AuthRequestState domain.AuthRequestState NeedRefreshToken bool + Issuer string } func NewAuthRequestWriteModel(ctx context.Context, id string) *AuthRequestWriteModel { @@ -68,6 +69,7 @@ func (m *AuthRequestWriteModel) Reduce() error { m.HintUserID = e.HintUserID m.AuthRequestState = domain.AuthRequestStateAdded m.NeedRefreshToken = e.NeedRefreshToken + m.Issuer = e.Issuer case *authrequest.SessionLinkedEvent: m.SessionID = e.SessionID m.UserID = e.UserID diff --git a/internal/command/auth_request_test.go b/internal/command/auth_request_test.go index 590e4086f4..c0b5f630f7 100644 --- a/internal/command/auth_request_test.go +++ b/internal/command/auth_request_test.go @@ -62,6 +62,7 @@ func TestCommands_AddAuthRequest(t *testing.T) { nil, nil, false, + "issuer", ), ), ), @@ -101,6 +102,7 @@ func TestCommands_AddAuthRequest(t *testing.T) { gu.Ptr("loginHint"), gu.Ptr("hintUserID"), false, + "issuer", ), ), ), @@ -127,6 +129,7 @@ func TestCommands_AddAuthRequest(t *testing.T) { MaxAge: gu.Ptr(time.Duration(0)), LoginHint: gu.Ptr("loginHint"), HintUserID: gu.Ptr("hintUserID"), + Issuer: "issuer", }, }, &CurrentAuthRequest{ @@ -150,6 +153,7 @@ func TestCommands_AddAuthRequest(t *testing.T) { MaxAge: gu.Ptr(time.Duration(0)), LoginHint: gu.Ptr("loginHint"), HintUserID: gu.Ptr("hintUserID"), + Issuer: "issuer", }, }, nil, @@ -234,6 +238,7 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { nil, nil, true, + "issuer", ), ), eventFromEventPusher( @@ -276,6 +281,7 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { nil, nil, true, + "issuer", ), ), ), @@ -317,6 +323,7 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { nil, nil, true, + "issuer", ), ), ), @@ -356,6 +363,7 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { nil, nil, true, + "issuer", ), ), ), @@ -418,6 +426,7 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { nil, nil, true, + "issuer", ), ), ), @@ -469,6 +478,7 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { nil, nil, true, + "issuer", ), ), ), @@ -527,6 +537,7 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { Audience: []string{"audience"}, ResponseType: domain.OIDCResponseTypeCode, ResponseMode: domain.OIDCResponseModeQuery, + Issuer: "issuer", }, SessionID: "sessionID", UserID: "userID", @@ -557,6 +568,7 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { nil, nil, true, + "issuer", ), ), ), @@ -616,6 +628,7 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { Audience: []string{"audience"}, ResponseType: domain.OIDCResponseTypeCode, ResponseMode: domain.OIDCResponseModeQuery, + Issuer: "issuer", }, SessionID: "sessionID", UserID: "userID", @@ -646,6 +659,7 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { nil, nil, true, + "issuer", ), ), ), @@ -706,6 +720,7 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { Audience: []string{"audience"}, ResponseType: domain.OIDCResponseTypeCode, ResponseMode: domain.OIDCResponseModeQuery, + Issuer: "issuer", }, SessionID: "sessionID", UserID: "userID", @@ -736,6 +751,7 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { nil, nil, true, + "issuer", ), ), ), @@ -797,6 +813,7 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { Audience: []string{"audience"}, ResponseType: domain.OIDCResponseTypeCode, ResponseMode: domain.OIDCResponseModeQuery, + Issuer: "issuer", }, SessionID: "sessionID", UserID: "userID", @@ -827,6 +844,7 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) { nil, nil, true, + "issuer", ), ), ), @@ -950,6 +968,7 @@ func TestCommands_FailAuthRequest(t *testing.T) { nil, nil, true, + "issuer", ), ), ), @@ -978,6 +997,7 @@ func TestCommands_FailAuthRequest(t *testing.T) { Audience: []string{"audience"}, ResponseType: domain.OIDCResponseTypeCode, ResponseMode: domain.OIDCResponseModeQuery, + Issuer: "issuer", }, }, }, @@ -1050,6 +1070,7 @@ func TestCommands_AddAuthRequestCode(t *testing.T) { gu.Ptr("loginHint"), gu.Ptr("hintUserID"), true, + "issuer", ), ), ), @@ -1088,6 +1109,7 @@ func TestCommands_AddAuthRequestCode(t *testing.T) { gu.Ptr("loginHint"), gu.Ptr("hintUserID"), true, + "issuer", ), ), eventFromEventPusher( diff --git a/internal/command/oidc_session_test.go b/internal/command/oidc_session_test.go index af1874a6bb..564c39460b 100644 --- a/internal/command/oidc_session_test.go +++ b/internal/command/oidc_session_test.go @@ -138,6 +138,7 @@ func TestCommands_CreateOIDCSessionFromAuthRequest(t *testing.T) { gu.Ptr("loginHint"), gu.Ptr("hintUserID"), true, + "issuer", ), ), eventFromEventPusher( @@ -182,6 +183,7 @@ func TestCommands_CreateOIDCSessionFromAuthRequest(t *testing.T) { gu.Ptr("loginHint"), gu.Ptr("hintUserID"), true, + "issuer", ), ), eventFromEventPusher( @@ -234,6 +236,7 @@ func TestCommands_CreateOIDCSessionFromAuthRequest(t *testing.T) { gu.Ptr("loginHint"), gu.Ptr("hintUserID"), true, + "issuer", ), ), eventFromEventPusher( @@ -331,6 +334,7 @@ func TestCommands_CreateOIDCSessionFromAuthRequest(t *testing.T) { gu.Ptr("loginHint"), gu.Ptr("hintUserID"), true, + "issuer", ), ), eventFromEventPusher( @@ -465,6 +469,7 @@ func TestCommands_CreateOIDCSessionFromAuthRequest(t *testing.T) { gu.Ptr("loginHint"), gu.Ptr("hintUserID"), true, + "issuer", ), ), eventFromEventPusher( @@ -610,6 +615,7 @@ func TestCommands_CreateOIDCSessionFromAuthRequest(t *testing.T) { gu.Ptr("loginHint"), gu.Ptr("hintUserID"), true, + "issuer", ), ), eventFromEventPusher( @@ -748,6 +754,7 @@ func TestCommands_CreateOIDCSessionFromAuthRequest(t *testing.T) { gu.Ptr("loginHint"), gu.Ptr("hintUserID"), false, + "issuer", ), ), eventFromEventPusher( diff --git a/internal/command/saml_request.go b/internal/command/saml_request.go index 17f56101ec..40e0643f0c 100644 --- a/internal/command/saml_request.go +++ b/internal/command/saml_request.go @@ -15,13 +15,14 @@ type SAMLRequest struct { ID string LoginClient string - ApplicationID string - ACSURL string - RelayState string - RequestID string - Binding string - Issuer string - Destination string + ApplicationID string + ACSURL string + RelayState string + RequestID string + Binding string + Issuer string + Destination string + ResponseIssuer string } type CurrentSAMLRequest struct { @@ -56,6 +57,7 @@ func (c *Commands) AddSAMLRequest(ctx context.Context, samlRequest *SAMLRequest) samlRequest.Binding, samlRequest.Issuer, samlRequest.Destination, + samlRequest.ResponseIssuer, )) if err != nil { return nil, err @@ -131,15 +133,16 @@ func (c *Commands) FailSAMLRequest(ctx context.Context, id string, reason domain func samlRequestWriteModelToCurrentSAMLRequest(writeModel *SAMLRequestWriteModel) (_ *CurrentSAMLRequest) { return &CurrentSAMLRequest{ SAMLRequest: &SAMLRequest{ - ID: writeModel.AggregateID, - LoginClient: writeModel.LoginClient, - ApplicationID: writeModel.ApplicationID, - ACSURL: writeModel.ACSURL, - RelayState: writeModel.RelayState, - RequestID: writeModel.RequestID, - Binding: writeModel.Binding, - Issuer: writeModel.Issuer, - Destination: writeModel.Destination, + ID: writeModel.AggregateID, + LoginClient: writeModel.LoginClient, + ApplicationID: writeModel.ApplicationID, + ACSURL: writeModel.ACSURL, + RelayState: writeModel.RelayState, + RequestID: writeModel.RequestID, + Binding: writeModel.Binding, + Issuer: writeModel.Issuer, + Destination: writeModel.Destination, + ResponseIssuer: writeModel.ResponseIssuer, }, SessionID: writeModel.SessionID, UserID: writeModel.UserID, diff --git a/internal/command/saml_request_model.go b/internal/command/saml_request_model.go index 7ba640cbe8..afd5b052c7 100644 --- a/internal/command/saml_request_model.go +++ b/internal/command/saml_request_model.go @@ -15,14 +15,15 @@ type SAMLRequestWriteModel struct { eventstore.WriteModel aggregate *eventstore.Aggregate - LoginClient string - ApplicationID string - ACSURL string - RelayState string - RequestID string - Binding string - Issuer string - Destination string + LoginClient string + ApplicationID string + ACSURL string + RelayState string + RequestID string + Binding string + Issuer string + Destination string + ResponseIssuer string SessionID string UserID string @@ -52,6 +53,7 @@ func (m *SAMLRequestWriteModel) Reduce() error { m.Binding = e.Binding m.Issuer = e.Issuer m.Destination = e.Destination + m.ResponseIssuer = e.ResponseIssuer m.SAMLRequestState = domain.SAMLRequestStateAdded case *samlrequest.SessionLinkedEvent: m.SessionID = e.SessionID diff --git a/internal/command/saml_request_test.go b/internal/command/saml_request_test.go index 761edde8fb..c11c87ec48 100644 --- a/internal/command/saml_request_test.go +++ b/internal/command/saml_request_test.go @@ -54,6 +54,7 @@ func TestCommands_AddSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), ), @@ -82,6 +83,7 @@ func TestCommands_AddSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), ), @@ -90,27 +92,29 @@ func TestCommands_AddSAMLRequest(t *testing.T) { args{ ctx: mockCtx, request: &SAMLRequest{ - LoginClient: "login", - ApplicationID: "application", - ACSURL: "acs", - RelayState: "relaystate", - RequestID: "request", - Binding: "binding", - Issuer: "issuer", - Destination: "destination", + LoginClient: "login", + ApplicationID: "application", + ACSURL: "acs", + RelayState: "relaystate", + RequestID: "request", + Binding: "binding", + Issuer: "issuer", + Destination: "destination", + ResponseIssuer: "responseissuer", }, }, &CurrentSAMLRequest{ SAMLRequest: &SAMLRequest{ - ID: "V2_id", - LoginClient: "login", - ApplicationID: "application", - ACSURL: "acs", - RelayState: "relaystate", - RequestID: "request", - Binding: "binding", - Issuer: "issuer", - Destination: "destination", + ID: "V2_id", + LoginClient: "login", + ApplicationID: "application", + ACSURL: "acs", + RelayState: "relaystate", + RequestID: "request", + Binding: "binding", + Issuer: "issuer", + Destination: "destination", + ResponseIssuer: "responseissuer", }, }, nil, @@ -187,6 +191,7 @@ func TestCommands_LinkSessionToSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), eventFromEventPusher( @@ -222,6 +227,7 @@ func TestCommands_LinkSessionToSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), ), @@ -255,6 +261,7 @@ func TestCommands_LinkSessionToSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), ), @@ -286,6 +293,7 @@ func TestCommands_LinkSessionToSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), ), @@ -340,6 +348,7 @@ func TestCommands_LinkSessionToSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), ), @@ -383,6 +392,7 @@ func TestCommands_LinkSessionToSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), ), @@ -431,15 +441,16 @@ func TestCommands_LinkSessionToSAMLRequest(t *testing.T) { details: &domain.ObjectDetails{ResourceOwner: "instanceID"}, authReq: &CurrentSAMLRequest{ SAMLRequest: &SAMLRequest{ - ID: "V2_id", - LoginClient: "login", - ApplicationID: "application", - ACSURL: "acs", - RelayState: "relaystate", - RequestID: "request", - Binding: "binding", - Issuer: "issuer", - Destination: "destination", + ID: "V2_id", + LoginClient: "login", + ApplicationID: "application", + ACSURL: "acs", + RelayState: "relaystate", + RequestID: "request", + Binding: "binding", + Issuer: "issuer", + Destination: "destination", + ResponseIssuer: "responseissuer", }, SessionID: "sessionID", UserID: "userID", @@ -462,6 +473,7 @@ func TestCommands_LinkSessionToSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), ), @@ -511,15 +523,16 @@ func TestCommands_LinkSessionToSAMLRequest(t *testing.T) { details: &domain.ObjectDetails{ResourceOwner: "instanceID"}, authReq: &CurrentSAMLRequest{ SAMLRequest: &SAMLRequest{ - ID: "V2_id", - LoginClient: "loginClient", - ApplicationID: "application", - ACSURL: "acs", - RelayState: "relaystate", - RequestID: "request", - Binding: "binding", - Issuer: "issuer", - Destination: "destination", + ID: "V2_id", + LoginClient: "loginClient", + ApplicationID: "application", + ACSURL: "acs", + RelayState: "relaystate", + RequestID: "request", + Binding: "binding", + Issuer: "issuer", + Destination: "destination", + ResponseIssuer: "responseissuer", }, SessionID: "sessionID", UserID: "userID", @@ -541,6 +554,7 @@ func TestCommands_LinkSessionToSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), ), @@ -591,15 +605,16 @@ func TestCommands_LinkSessionToSAMLRequest(t *testing.T) { details: &domain.ObjectDetails{ResourceOwner: "instanceID"}, authReq: &CurrentSAMLRequest{ SAMLRequest: &SAMLRequest{ - ID: "V2_id", - LoginClient: "loginClient", - ApplicationID: "application", - ACSURL: "acs", - RelayState: "relaystate", - RequestID: "request", - Binding: "binding", - Issuer: "issuer", - Destination: "destination", + ID: "V2_id", + LoginClient: "loginClient", + ApplicationID: "application", + ACSURL: "acs", + RelayState: "relaystate", + RequestID: "request", + Binding: "binding", + Issuer: "issuer", + Destination: "destination", + ResponseIssuer: "responseissuer", }, SessionID: "sessionID", UserID: "userID", @@ -622,6 +637,7 @@ func TestCommands_LinkSessionToSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), ), @@ -672,15 +688,16 @@ func TestCommands_LinkSessionToSAMLRequest(t *testing.T) { details: &domain.ObjectDetails{ResourceOwner: "instanceID"}, authReq: &CurrentSAMLRequest{ SAMLRequest: &SAMLRequest{ - ID: "V2_id", - LoginClient: "loginClient", - ApplicationID: "application", - ACSURL: "acs", - RelayState: "relaystate", - RequestID: "request", - Binding: "binding", - Issuer: "issuer", - Destination: "destination", + ID: "V2_id", + LoginClient: "loginClient", + ApplicationID: "application", + ACSURL: "acs", + RelayState: "relaystate", + RequestID: "request", + Binding: "binding", + Issuer: "issuer", + Destination: "destination", + ResponseIssuer: "responseissuer", }, SessionID: "sessionID", UserID: "userID", @@ -703,6 +720,7 @@ func TestCommands_LinkSessionToSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), ), @@ -817,6 +835,7 @@ func TestCommands_FailSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), samlrequest.NewFailedEvent(mockCtx, &samlrequest.NewAggregate("V2_id", "instanceID").Aggregate, @@ -850,6 +869,7 @@ func TestCommands_FailSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), ), @@ -870,15 +890,16 @@ func TestCommands_FailSAMLRequest(t *testing.T) { details: &domain.ObjectDetails{ResourceOwner: "instanceID"}, samlReq: &CurrentSAMLRequest{ SAMLRequest: &SAMLRequest{ - ID: "V2_id", - LoginClient: "login", - ApplicationID: "application", - ACSURL: "acs", - RelayState: "relaystate", - RequestID: "request", - Binding: "binding", - Issuer: "issuer", - Destination: "destination", + ID: "V2_id", + LoginClient: "login", + ApplicationID: "application", + ACSURL: "acs", + RelayState: "relaystate", + RequestID: "request", + Binding: "binding", + Issuer: "issuer", + Destination: "destination", + ResponseIssuer: "responseissuer", }, }, }, diff --git a/internal/command/saml_session_test.go b/internal/command/saml_session_test.go index 12cc0683c5..4781381cc4 100644 --- a/internal/command/saml_session_test.go +++ b/internal/command/saml_session_test.go @@ -99,6 +99,7 @@ func TestCommands_CreateSAMLSessionFromSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), ), @@ -129,6 +130,7 @@ func TestCommands_CreateSAMLSessionFromSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), eventFromEventPusher( @@ -167,6 +169,7 @@ func TestCommands_CreateSAMLSessionFromSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), eventFromEventPusher( @@ -248,6 +251,7 @@ func TestCommands_CreateSAMLSessionFromSAMLRequest(t *testing.T) { "binding", "issuer", "destination", + "responseissuer", ), ), eventFromEventPusher( diff --git a/internal/repository/authrequest/auth_request.go b/internal/repository/authrequest/auth_request.go index 99f034333b..75624e3a21 100644 --- a/internal/repository/authrequest/auth_request.go +++ b/internal/repository/authrequest/auth_request.go @@ -38,6 +38,7 @@ type AddedEvent struct { LoginHint *string `json:"login_hint,omitempty"` HintUserID *string `json:"hint_user_id,omitempty"` NeedRefreshToken bool `json:"need_refresh_token,omitempty"` + Issuer string `json:"issuer,omitempty"` } func (e *AddedEvent) Payload() interface{} { @@ -66,6 +67,7 @@ func NewAddedEvent(ctx context.Context, loginHint, hintUserID *string, needRefreshToken bool, + issuer string, ) *AddedEvent { return &AddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( @@ -89,6 +91,7 @@ func NewAddedEvent(ctx context.Context, LoginHint: loginHint, HintUserID: hintUserID, NeedRefreshToken: needRefreshToken, + Issuer: issuer, } } diff --git a/internal/repository/samlrequest/saml_request.go b/internal/repository/samlrequest/saml_request.go index b3ecdd753e..aca8da99fe 100644 --- a/internal/repository/samlrequest/saml_request.go +++ b/internal/repository/samlrequest/saml_request.go @@ -19,14 +19,15 @@ const ( type AddedEvent struct { *eventstore.BaseEvent `json:"-"` - LoginClient string `json:"login_client,omitempty"` - ApplicationID string `json:"application_id,omitempty"` - ACSURL string `json:"acs_url,omitempty"` - RelayState string `json:"relay_state,omitempty"` - RequestID string `json:"request_id,omitempty"` - Binding string `json:"binding,omitempty"` - Issuer string `json:"issuer,omitempty"` - Destination string `json:"destination,omitempty"` + LoginClient string `json:"login_client,omitempty"` + ApplicationID string `json:"application_id,omitempty"` + ACSURL string `json:"acs_url,omitempty"` + RelayState string `json:"relay_state,omitempty"` + RequestID string `json:"request_id,omitempty"` + Binding string `json:"binding,omitempty"` + Issuer string `json:"issuer,omitempty"` + Destination string `json:"destination,omitempty"` + ResponseIssuer string `json:"response_issuer,omitempty"` } func (e *AddedEvent) SetBaseEvent(event *eventstore.BaseEvent) { @@ -51,6 +52,7 @@ func NewAddedEvent(ctx context.Context, binding string, issuer string, destination string, + responseIssuer string, ) *AddedEvent { return &AddedEvent{ BaseEvent: eventstore.NewBaseEventForPush( @@ -58,14 +60,15 @@ func NewAddedEvent(ctx context.Context, aggregate, AddedType, ), - LoginClient: loginClient, - ApplicationID: applicationID, - ACSURL: acsURL, - RelayState: relayState, - RequestID: requestID, - Binding: binding, - Issuer: issuer, - Destination: destination, + LoginClient: loginClient, + ApplicationID: applicationID, + ACSURL: acsURL, + RelayState: relayState, + RequestID: requestID, + Binding: binding, + Issuer: issuer, + Destination: destination, + ResponseIssuer: responseIssuer, } }