feat(auth): implemented single sign out
This commit is contained in:
parent
d88acf4634
commit
b947037ea2
@ -1,4 +1,4 @@
|
|||||||
# SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
# SPDX-FileCopyrightText: 2022-2024 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,David Mosbach <david.mosbach@uniworx.de>
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
@ -139,3 +139,5 @@ FormHoneypotNamePlaceholder: Name
|
|||||||
FormHoneypotComment: Kommentar
|
FormHoneypotComment: Kommentar
|
||||||
FormHoneypotCommentPlaceholder: Kommentar
|
FormHoneypotCommentPlaceholder: Kommentar
|
||||||
FormHoneypotFilled: Bitte füllen Sie keines der verstecken Felder aus
|
FormHoneypotFilled: Bitte füllen Sie keines der verstecken Felder aus
|
||||||
|
|
||||||
|
SingleSignOut: Abmeldung bei Azure
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>
|
# SPDX-FileCopyrightText: 2022-2024 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Winnie Ros <winnie.ros@campus.lmu.de>,David Mosbach <david.mosbach@uniworx.de>
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
@ -140,3 +140,5 @@ FormHoneypotNamePlaceholder !ident-ok: Name
|
|||||||
FormHoneypotComment: Comment
|
FormHoneypotComment: Comment
|
||||||
FormHoneypotCommentPlaceholder: Comment
|
FormHoneypotCommentPlaceholder: Comment
|
||||||
FormHoneypotFilled: Please do not fill in any of the hidden fields
|
FormHoneypotFilled: Please do not fill in any of the hidden fields
|
||||||
|
|
||||||
|
SingleSignOut: Azure logout
|
||||||
|
|||||||
4
routes
4
routes
@ -1,4 +1,4 @@
|
|||||||
-- SPDX-FileCopyrightText: 2022-2023 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Wolfgang Witt <Wolfgang.Witt@campus.lmu.de>
|
-- SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Steffen Jost <jost@tcs.ifi.lmu.de>,Wolfgang Witt <Wolfgang.Witt@campus.lmu.de>,David Mosbach <david.mosbach@uniworx.de>
|
||||||
--
|
--
|
||||||
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
@ -46,6 +46,8 @@
|
|||||||
/static StaticR EmbeddedStatic appStatic !free
|
/static StaticR EmbeddedStatic appStatic !free
|
||||||
/auth AuthR Auth getAuth !free
|
/auth AuthR Auth getAuth !free
|
||||||
|
|
||||||
|
/ssout SSOutR GET !free -- single sign-out (OIDC)
|
||||||
|
|
||||||
/metrics MetricsR GET !free -- verify if this can be free
|
/metrics MetricsR GET !free -- verify if this can be free
|
||||||
|
|
||||||
/err ErrorR GET !free
|
/err ErrorR GET !free
|
||||||
|
|||||||
@ -164,6 +164,7 @@ import Handler.PrintCenter
|
|||||||
import Handler.ApiDocs
|
import Handler.ApiDocs
|
||||||
import Handler.Swagger
|
import Handler.Swagger
|
||||||
import Handler.Firm
|
import Handler.Firm
|
||||||
|
import Handler.SingleSignOut
|
||||||
|
|
||||||
import ServantApi () -- YesodSubDispatch instances
|
import ServantApi () -- YesodSubDispatch instances
|
||||||
import Servant.API
|
import Servant.API
|
||||||
|
|||||||
@ -11,12 +11,13 @@ module Auth.OAuth2
|
|||||||
, mockPluginName
|
, mockPluginName
|
||||||
, queryOAuth2User
|
, queryOAuth2User
|
||||||
, UserDataException
|
, UserDataException
|
||||||
|
, singleSignOut
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.Maybe (fromJust)
|
import Data.Maybe (fromJust)
|
||||||
import Data.Text
|
import Data.Text
|
||||||
|
|
||||||
import Import.NoFoundation hiding (unpack)
|
import Import.NoFoundation hiding (pack, unpack)
|
||||||
|
|
||||||
import Network.HTTP.Simple (httpJSONEither, getResponseBody, JSONException)
|
import Network.HTTP.Simple (httpJSONEither, getResponseBody, JSONException)
|
||||||
|
|
||||||
@ -148,3 +149,23 @@ instance Show RequestBody where
|
|||||||
show (RequestBodyLBS x) = show x
|
show (RequestBodyLBS x) = show x
|
||||||
show _ = error ":("
|
show _ = error ":("
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
---- Single Sign-Out ----
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
singleSignOut :: forall a m. (MonadHandler m)
|
||||||
|
=> Maybe Text -- ^ redirect uri
|
||||||
|
-> m a
|
||||||
|
singleSignOut mRedirect = do
|
||||||
|
# ifdef DEVELOPMENT
|
||||||
|
port <- liftIO $ fromJust <$> lookupEnv "OAUTH2_SERVER_PORT"
|
||||||
|
let base = "http://localhost:" <> pack port <> "/logout"
|
||||||
|
# else
|
||||||
|
let base = "" -- TODO find out fraport oidc end_session_endpoint
|
||||||
|
# endif
|
||||||
|
endpoint = case mRedirect of
|
||||||
|
Just r -> base <> "?post_logout_redirect_uri=" <> r
|
||||||
|
Nothing -> base
|
||||||
|
redirect endpoint
|
||||||
|
|
||||||
|
|||||||
@ -174,6 +174,11 @@ instance YesodAuth UniWorX where
|
|||||||
|
|
||||||
addMessage Success . toHtml $ mr Auth.NowLoggedIn
|
addMessage Success . toHtml $ mr Auth.NowLoggedIn
|
||||||
|
|
||||||
|
-- onLogout = do
|
||||||
|
-- AppSettings{..} <- getsYesod appSettings'
|
||||||
|
-- when appSingleSignOn $ singleSignOut @UniWorX Nothing
|
||||||
|
|
||||||
|
|
||||||
onErrorHtml dest msg = do
|
onErrorHtml dest msg = do
|
||||||
addMessage Error $ toHtml msg
|
addMessage Error $ toHtml msg
|
||||||
redirect dest
|
redirect dest
|
||||||
|
|||||||
@ -73,6 +73,7 @@ breadcrumb :: ( BearerAuthSite UniWorX
|
|||||||
=> Route UniWorX
|
=> Route UniWorX
|
||||||
-> m Breadcrumb
|
-> m Breadcrumb
|
||||||
breadcrumb (AuthR _) = i18nCrumb MsgMenuLogin $ Just NewsR
|
breadcrumb (AuthR _) = i18nCrumb MsgMenuLogin $ Just NewsR
|
||||||
|
breadcrumb SSOutR = i18nCrumb MsgSingleSignOut Nothing
|
||||||
breadcrumb (StaticR _) = i18nCrumb MsgBreadcrumbStatic Nothing
|
breadcrumb (StaticR _) = i18nCrumb MsgBreadcrumbStatic Nothing
|
||||||
breadcrumb (WellKnownR _) = i18nCrumb MsgBreadcrumbWellKnown Nothing
|
breadcrumb (WellKnownR _) = i18nCrumb MsgBreadcrumbWellKnown Nothing
|
||||||
breadcrumb MetricsR = i18nCrumb MsgBreadcrumbMetrics Nothing
|
breadcrumb MetricsR = i18nCrumb MsgBreadcrumbMetrics Nothing
|
||||||
@ -546,7 +547,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
|||||||
, navIcon = IconMenuLogout
|
, navIcon = IconMenuLogout
|
||||||
, navLink = NavLink
|
, navLink = NavLink
|
||||||
{ navLabel = MsgMenuLogout
|
{ navLabel = MsgMenuLogout
|
||||||
, navRoute = AuthR LogoutR
|
, navRoute = SSOutR -- AuthR LogoutR
|
||||||
, navAccess' = NavAccessHandler $ is _Just <$> maybeAuthId
|
, navAccess' = NavAccessHandler $ is _Just <$> maybeAuthId
|
||||||
, navType = NavTypeLink { navModal = False }
|
, navType = NavTypeLink { navModal = False }
|
||||||
, navQuick' = mempty
|
, navQuick' = mempty
|
||||||
|
|||||||
23
src/Handler/SingleSignOut.hs
Normal file
23
src/Handler/SingleSignOut.hs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
-- SPDX-FileCopyrightText: 2024 David Mosbach <david.mosbach@uniworx.de>
|
||||||
|
--
|
||||||
|
-- SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
module Handler.SingleSignOut
|
||||||
|
( getSSOutR
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Import
|
||||||
|
import Auth.OAuth2 (singleSignOut)
|
||||||
|
import qualified Network.Wai as W
|
||||||
|
|
||||||
|
|
||||||
|
getSSOutR :: Handler Html
|
||||||
|
getSSOutR = do
|
||||||
|
app <- getYesod
|
||||||
|
let logoutR = intercalate "/" . fst . renderRoute $ AuthR LogoutR
|
||||||
|
root = case approot of
|
||||||
|
ApprootRequest f -> f app W.defaultRequest
|
||||||
|
_ -> error "approt implementation changed"
|
||||||
|
AppSettings{..} <- getsYesod appSettings'
|
||||||
|
if appSingleSignOn then singleSignOut (Just $ root <> "/" <> logoutR) else redirect (AuthR LogoutR)
|
||||||
|
|
||||||
Reference in New Issue
Block a user